靜態分派與動態分派
阿新 • • 發佈:2019-02-08
靜態分派
先看定義:所有依賴靜態型別來定位方法執行版本的分派動作成為靜態分派。
靜態分派典型的應用方法過載
你能看出下面程式碼的輸出什麼嗎????????????
class Dog{} class WhiteDog extends Dog{} class BlackDog extends Dog{} public class Person { public void feed(Dog dog){ System.out.println("feed Dog"); } public void feed(WhiteDog Dog){ System.out.println("feed WhiteDog"); } public void feed(BlackDog Dog){ System.out.println("feed BlackDog"); } public static void main(String[] args) { Dog wd = new WhiteDog(); Dog bd = new BlackDog(); Person p = new Person(); p.feed(wd); p.feed(bd); } }
輸出:
feed dog
feed dog
這個結果可能會讓很多人大跌眼鏡,這樣的結果是因為過載是靜態分派,在編譯器執行的,取決於變數的宣告型別,說白了就是在編譯時feed()方法中的引數都是Dog型別的,所以最後的只會呼叫第一個過載方法。
動態分派
還是先看定義:發生在執行期,動態分派,動態的置換掉某個方法。
它和多型性的另外一個重要體現——重寫 有著很密切的關係。
還是用上面的例子:
class Dog{ public void eat(){ System.out.println("Dog eat"); } } public class BlackDog extends Dog{ public void eat(){ System.out.println("black Dog eat"); } public static void main(String[] args){ Dog Dog = new BlackDog(); Dog.eat(); } }
輸出:
black Dog eat
這個結果並不出人意料,對於習慣了面向物件思維的Java程式設計師會覺得完全是理所當然的。這樣的結果是因為在執行期發生了向下轉型,就是動態分派了。