繼承和多型的相關問題
探索一
繼承條件下的構造方法呼叫
1.繼承如果是多重繼承,在呼叫建構函式方面,先從父類呼叫
再依次是下面的子類。因為建構函式的作用是在建立了一個型別後
為了能用,得把這個型別初始化,分配記憶體空間。
從父類依次到子類就是保證例項變數都可以被正確的初始化。
探索二
super的用法
package TestInherits; class Grandparent { public Grandparent() { System.out.println("GrandParent Created."); } publicGrandparent(String string) { System.out.println("GrandParent Created.String:" + string); } } class Parent extends Grandparent { public Parent() { super("Hello.Grandparent."); System.out.println("Parent Created"); // super("Hello.Grandparent.");} } class Child extends Parent { public Child() { System.out.println("Child Created"); } } public class TestInherits { public static void main(String args[]) { Child c = new Child(); } }
如果用了super呼叫基類,那麼這個super必須寫在第一行
super一出現,直接訪問父類中的建構函式,因為這個super
的型別是String型別,所以呼叫的父類中引數為String的型別。
探索三
奇怪的現象
public class ExplorationJDKSource { /** * @param args */ public static void main(String[] args) { System.out.println(new A()); } } class A{}
這個程式的執行結果
[email protected]
public void println(Object x),這一方法內部呼叫了valueOf方法
valueOf方法內部又呼叫了Object.toString方法
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
hashCode方法是本地方法,由JVM設計者實現:public native int hashCode();
探索四
在子類中,若要呼叫父類中被覆蓋的方法,可以使用super關鍵字
1 public class FatherAndSon { 2 3 public static void main(String args[]) { 4 FatherAndSon s=new FatherAndSon(); 5 s.Test(); 6 } 7 public void Test() { 8 Son s=new Son(); 9 s.test(); 10 11 } 12 class Father {//宣告父類 13 public void test() {//宣告父類中的測試程式碼 14 System.out.println("father"); 15 16 } 17 } 18 class Son extends Father{//宣告子類,並繼承父類 19 public void test() {//覆蓋父類的測試類 20 System.out.println("son"); 21 super.test();//使用super呼叫父類的測試類 22 } 23 } 24 }
當super被註釋時的輸出,父類的測試類沒有輸出,也就沒有被呼叫。
呼叫super時的輸出,明顯父類的測試類也被呼叫了,說明當父類中的方法被覆蓋的時候,要想訪問父類中方法就要使用super字元。
多型:
探索一
public class ParentChildTest { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child child=new Child(); child.printValue(); parent=child; parent.printValue(); parent.myValue++; //System.out.println(parent.myValue); parent.printValue(); ((Child)parent).myValue++; //System.out.println(parent.myValue); //System.out.println(child.myValue); parent.printValue(); } } class Parent{ public int myValue= 100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }
結果為:
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201
當子類和父類方法名和內容相同時,具體呼叫哪一個,由物件
決定,物件調哪個就用那個方法