動手動腦-4
package 動手動腦; public class 基類 { public 基類() { System.out.println("基類 Created."); } public 基類(String string) { System.out.println("基類 Created.String:" + string); } } package 動手動腦; public class 父類 extends 基類 {public 父類() { super("Hello.Grandparent."); System.out.println("父類 Created"); //super("Hello.Grandparent."); } } package 動手動腦; public class 子類 extends 父類{ public 子類() { System.out.println("子類 Created"); } } package 動手動腦; publicclass 測試 { public static void main(String args[]) { 子類 c = new 子類(); } }
當super在父類構造函數上面時,最終的運行結果為:
基類 Created.String:Hello.Grandparent.
父類 Created
子類 Created
先調用基類有參構造函數,輸出基類 Created.String:Hello.Grandparent.,然後再依次調用父類和子類構造函數。當super在父類構造函數的下面時,出現錯誤,程序無法運行。所以得出結論,用super調用基類的構造方法,必須是子類的第一個語句。
構造方法用於對基類的初始化。構造一個對象,先調用其構造方法,來初始化其成員函數和成員變量。子類擁有父的成員變量和成員方法,如果不調用,則從父類繼承而來的成員變量和成員方法得不到正確的初始化。
package 動手動腦; public class 父類2 { public void sleeping() { System.out.println("父親在睡覺。"); } } package 動手動腦; public class 子類2 extends 父類2{ public void sleeping() { super.sleeping(); System.out.println("孩子在睡覺。"); } } package 動手動腦; public class 測試2 { public static void main(String[] args) { 子類2 z=new 子類2(); z.sleeping(); } }
這個程序的運行結果為:
父親在睡覺。
孩子在睡覺。
子類把父類的方法覆蓋,通過super關鍵字來調用父類中的方法。
class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{} public class TestCast { public static void main(String args[]) { Mammal m; Dog d=new Dog(); Cat c=new Cat(); m=d; //d=m; d=(Dog)m; //d=c; //c=(Cat)m; } }
通過運行我發現,當放開d=m這一行和d=c這一行的註釋之後,編譯出現錯誤,當放開c=(Cat)m這一行的註釋之後,運行出現錯誤。因為m是父類創建的對象,而d是子類創建的對象,所以當d=m時需要進行類型強制轉換,而沒有轉換會使編譯出現錯誤。d=c這一行出現錯誤的原因是不能讓同等地位的對象進行轉換。
package 動手動腦; public class Child extends Parent { public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } } package 動手動腦; public class Parent { public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } package 動手動腦; public class ParentChildTest { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child c=new Child(); c.printValue(); parent=c; parent.printValue(); parent.myValue++; parent.printValue(); ((Child)parent).myValue++; parent.printValue(); } }
這個程序運行之後的結果為:
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201
前兩條結果不用解釋,第三條,parent=c; 將子類變量賦給基類變量,這樣就是體現了多態性,和Parent parent=new Child();的效果是一樣的,此時當對象parent引用方法時,引用的是子類的方法,而當此對象引用變量時,引用的是父類的變量,所以在parent.printValue();時,輸出的是子類中方法的輸出語句,而parent.myValue++;時,增加的是父類變量myValue的值,而子類中myValue的值不變,所以當此對象再次引用此方法時,輸出的仍是子類中此方法中的輸出語句,而myValue的值不變,當使用了強制類型轉換之後,((Child)parent).myValue++;此時(Child)parent就相當於是子類對象,引用變量myValue時,增加的是子類myValue的值,而調用方法之後,輸出子類方法中的輸出語句,而myValue得值發生變化。
動手動腦-4