## 什么是多態:
多態不但能夠改善代碼的組織結構和可讀性,還能夠創建可擴展的程序。在Java中,所有的方法都是通過動態綁定實現多態的。將一個方法調用同一個方法主體關聯起來被稱作綁定。動態綁定的含義是在運行時根據對象的類型進行綁定。動態綁定也叫作后期綁定或運行時綁定。Java中除了static方法和final方法(private方法屬于final方法)之外,其他所有的方法都是后期綁定。這意味著通常情況下,我們不必判定是否應該進行后期綁定——它會自動發生。也就是說,在Java中,只有普通的方法是多態的,static方法、private方法、final方法以及成員變量都不是多態的,都屬于編譯期綁定。
## 注意事項一:“覆蓋”私有方法
例子:
~~~
public class PrivateOverride {
private void f(){
System.out.println("private f()");
}
public static void main(String[] args){
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride{
public void f(){
System.out.println("public f()");
}
}
~~~
輸出:
~~~
private f()
~~~
說明:對于private方法來說,它默認是final的,不允許被更改,導出類看不到private方法,不能被繼承,也就沒有“覆蓋(override)”這一說。當導出類有一個同名的符合覆蓋規則的方法時,其實導出類中的該方法是一個全新的方法。但是當我們試圖對私有方法進行覆蓋并使用多態時,雖然編譯器不會報錯,但私有方法不支持多態,最終調用的是基類中的方法。
## 注意事項二:域與靜態方法不支持多態
例子:
~~~
class Super{
public int field = 0;
public int getField(){
return field;
}
public static String say(){
return "Super static function.";
}
}
class Sub extends Super{
public int field = 1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
public static String say(){
return "Sub static function.";
}
}
public class FieldAccess{
public static void main(String[] args){
Super sup = new Sub();
System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
System.out.println("sup.say = " + sup.say());
Sub sub = new Sub();
System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField() + ", sub.getSuperField() = " + sub.getSuperField());
System.out.println("sub.say = " + sub.say());
}
}
~~~
輸出:
~~~
sup.field = 0, sup.getField() = 1
sup.say = Super static function.
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0
sub.say = Sub static function.
~~~
說明:對于域和靜態方法,是不支持多態的,他們都屬于前期綁定,即在編譯期實現的綁定。故域和靜態方法只能綁定到基類的域和方法,不支持動態綁定。
(以上代碼來自Java編程思想第四版,說明來自Java編程思想第四版中關于多態的章節的整理,僅用于學習和交流)