關於繼承與多型的簡單認識
阿新 • • 發佈:2018-11-04
(1)繼承條件下的構造方法呼叫
package Demo1; class Grandparent { public Grandparent() { System.out.println("GrandParent Created."); } public Grandparent(String string) { System.out.println("GrandParent Created.String:" + string); } } classParent 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呼叫父類構造方法,必須將函式放在子類方法的第一句。
(2)直接輸出類建立的物件
public class ExplorationJDKSource { /** * @param args*/ public static void main(String[] args) { System.out.println(new A()); } } class A{}
輸出:
根據Javap -c反彙編以上程式碼:
最後,可根據反彙編追查原始碼:
System.out.println的原始碼如下:
public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); } }
其中的valueOf原始碼追查:
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
toString原始碼追查:
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
所以,我們可以明白了為何輸出了一串很詭異的字串。
(3)toString的簡單認識
package Demo1; public class Fruit { public String toString() { return "Fruit toString."; } public static void main(String args[]) { Fruit f=new Fruit(); System.out.println("f="+f); System.out.println("f="+f.toString()); } }
輸出;
所以,在“+”號運算中,與字串相連的物件總是預設呼叫toString方法。
(4)“變態”的多型
package Demo1; 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++; parent.printValue(); ((Child)parent).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); } }
輸出:
結論:
當子類與父類擁有一樣的方法,並且讓一個父類變數引用一個子類物件時,到底呼叫哪個方法,由物件自己的“真實”型別所決定,這就是說:物件是子型別的,它就呼叫子型別的方法,是父型別的,它就呼叫父型別的方法。