下面舉例進行分析: java
Student st=new Student();//Student爲子類 Person p=st;//Person 爲超類 p.sayHello();//該方法在超類和子類中都存在
分析:
* 爲何子類的類型的對象實例能夠覆給超類引用?
自動實現向上轉型。經過該語句,編譯器自動將子類實例向上移動,成爲通用類型Person;
*p.sayHello()將執行子類仍是父類定義的方法?
子類的。在運行時期,將根據p這個對象引用實際的類型來獲取對應的方法。因此纔有多態性。一個超類類的對象引用,被賦予不一樣的子類對象引用,執行該方法時,將表現出不一樣的行爲。
特別注意的是:
在p=st的時候,仍然是存在兩個句柄,p和st,可是p和st擁有同一塊數據內存塊和不一樣的函數表。 函數
動態連接:當父類中的一個方法只有在父類中定義而在子類中沒有重寫的狀況下,才能夠被父類類型的引用調用; 對於父類中定義的方法,若是子類中重寫了該方法,那麼父類類型的引用將會調用子類中的這個方法,這就是動態鏈接。 spa
總結它爲:
1、使用超類型的引用指向子類的對象;
2、該引用只能調用超類中定義的方法和變量;
3、若是子類中重寫了超類中的一個方法,那麼在調用這個方法的時候,將會調用子類中的這個方法;(動態鏈接、動態調用)
4、變量不能被重寫(覆蓋),」重寫「的概念只針對方法,若是在子類中」重寫「了基類中的變量,那麼在編譯時會報錯。
經過將子類對象引用賦值給超類對象引用變量來實現動態方法調用。
java 的這種機制遵循一個原則:當超類對象引用變量引用子類對象時,被引用對象的類型而不是引用變量的類型決定了調用誰的成員方法,可是這個被調用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
1. 若是a是類A的一個引用,那麼,a能夠指向類A的一個實例,或者說指向類A的一個子類。
2. 若是a是接口A的一個引用,那麼,a必須指向實現了接口A的一個類的實例。 .net