前不久分享了一篇文章,將的是java動態綁定和向上轉型,說實話還沒仔細看這篇文章,自己很懶。不過對於給的第一個程式,作者的解釋是參數在編譯階段被匹配,得出的總結是重載函數的實際調用版本由編譯器綁定決定,而覆蓋函數的實際調用版本由動態綁定決定。還是有點道理,不過對於程式,我覺得剛開始看的時候,未免把他想的太複雜了。先貼上程式,我修改了點。
class Base{ public void foo(Base x){ System.out.println("Base.Base"); } public void foo(Derived x){ System.out.println("Base.Derived"); } } class Derived extends Base{ public void foo(Base x){ System.out.println("Derived.Base"); } public void foo(Derived x){ System.out.println("Derived.Derived"); } } public class Main{ public static void whichFoo(Base arg1, Base arg2){ arg1.foo(arg2); //System.out.println();arg2.foo(arg1); arg1.foo(arg1);arg2.foo(arg2); } public static void main(String[] args){ Base b = new Base(); Derived d = new Derived(); whichFoo(b,b); //b.foo(b);System.out.println(); whichFoo(b,d); //b.foo(d);System.out.println(); whichFoo(d,b); //d.foo(b);System.out.println(); whichFoo(d,d); //d.foo(d); } }
對於whichFoo中的參數,既然已經給定了是Base,那麼在函數裡調用xx.foo(argx)時,顯然argx就是Base了,不會再動態改變了,不用想太複雜了!
如果將Base.foo(Base x)函數取消掉,那麼編譯時間就給出錯誤:無法將foo(Derivide)應用於Base。
所以,對於調用重載的方法,編譯器會根據參數決定調用哪個方法,所以作者總結的“重載函數的實際調用版本由編譯器綁定決定,而覆蓋函數的實際調用版本由動態綁定決定”還是比較容易理解的。但是也不應把參數傳遞想的太複雜了!