面向對象的三大特徵:封裝,繼承和多態。多態是面向程序設計中代碼重用的一個重要機制,它表示當同一操做做用在不一樣對象時,會有不一樣的語義。java
Java 多態主要有如下兩種表現方式:ide
1)方法重載(overload)。重載是指同一類中有多個同名方法,可是這些方法必須在參數列表上加以區分,要麼參數個數不一樣,要麼在相同位置上的參數類型不一樣,返回值和訪問控制符能夠不一樣。spa
2)方法的覆蓋(override)。子類能夠覆蓋父類的方法。父類的引用不但能夠指向其實例對象,也可以指向子類的實例對象。接口的引用變量也能夠指向其實現類的實例對象。設計
一、方法覆蓋要求方法名,參數列表,返回值都必須相同,假如參數列表不一樣就屬於重載,假如返回值不一樣,編譯通不過!code
二、另外覆蓋方法權限不能低於被覆蓋方法,例如父類是public 子類就必須是public,假如是protected就通不過。對象
三、重寫方法必定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常。例如:父類的一個方法申明瞭一個檢查異常IOException,在重寫這個方法是就不能拋出Exception,只能拋出IOException的子類異常,能夠拋出非檢查異常。blog
而程序的調用方法是在運行期才動態綁定的,就是引用變量所指向的具體實例對象的方法,而不是引用變量的類型中定義的方法。這種動態綁定實現了多態。只有運行時纔可以肯定具體調用哪一個方法。所以經過方法覆蓋的實例也稱爲運行時多態。繼承
注意成員變量是沒法實現多態的,成員變量的取值取決於定義變量的類型。接口
public class Father { public int i=1; public void a() { System.out.println("father a"); } public void b() { System.out.println("father b"); } }
public class Son extends Father{ public int i=5; public void a() { System.out.println("Son a"); } public void b() { System.out.println("Son b"); } public void c() { System.out.println("Son c"); } }
public static void main(String[] args) { Father father=new Son(); father.a(); father.b(); //father.c(); error System.out.println(father.i); Son son=(Son)father; //父類強制轉換成子類的原則:父類型的引用指向的是哪一個子類的實例,就能轉換成哪一個子類的引用 son.c(); System.out.println(son.i);
//會拋出異常 java.lang.ClassCastException: Father cannot be cast to Son
//Son son=(Son)new Father();編譯器
}
輸出:
Son a Son b 1 Son c 5
PS:Java動態綁定和靜態綁定
這兩種綁定方式是根據是否可以在編譯器肯定要執行的方法來區分的。
其中只有final,static,private和構造方法是靜態綁定,其餘的所有是動態綁定,即在運行期才能肯定要執行的方法。
final 類的方法沒法被覆蓋,子類能夠調用這個方法,可是都是父類的這個方法,因此在編譯器就可以知道。
static是類方法,引用變量是什麼類型的,調用的就是什麼類型的靜態方法,注意子類能夠轉換成父類,由於子類包含了父類的所有,而父類不能轉換成子類。
Father father=new Son(); father.say(); Son son=new Son(); son.say(); father=son; father.say();
輸出
father say
son say
father say
這個例子中父類和子類都有一個同名的靜態方法say(),當引用變量是father類型的,那麼調用的就是Father類型的,當引用變量是Son類型的,那麼調用的就是Son類型的。
private是類私有的,只能在類內部調用。
構造方法不能被覆蓋,能夠直接綁定。
其餘的方法調用都是動態綁定,相似Objective c中的isa,經過instanceof 先找到對象屬於哪類類型,而後查找對象的方法表,有一樣簽名的就執行,不然到父類去查找。