繼承與多型動手動腦總結
一:繼承條件下的構造方法呼叫
程式程式碼:
class Grandparent { public Grandparent() { System.out.println("GrandParent Created."); } public Grandparent(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"); } } publicclass TestInherits { public static void main(String args[]) { Child c = new Child(); } }
程式截圖:
結論:(1)通過 super 呼叫基類構造方法,必須是子類構造方法中的第一個語句。
(2)當我們去執行程式碼的時候,父類的建構函式會先於子類的建構函式。然後,在當我們把子類中的父類的構造方法取消註釋,我們會發現同樣的結果,然後當我們把父類的構造方法放入子類的構造方法之後,我們會發現,程式碼無法編譯通過,由此得到結論。
二:怎樣判斷物件是否可以轉換?
可以使用instanceof運算子判斷一個物件是否可以轉換為指定的型別:
Object obj="Hello";
if(obj instanceof String)
System.out.println("obj物件可以被轉換為字串");
程式程式碼:
public class TestInstanceof { public static void main(String[] args) { //宣告hello時使用Object類,則hello的編譯型別是Object,Object是所有類的父類 //但hello變數的實際型別是String Object hello = "Hello"; //String是Object類的子類,所以返回true。 System.out.println("字串是否是Object類的例項:" + (hello instanceof Object)); //返回true。 System.out.println("字串是否是String類的例項:" + (hello instanceof String)); //返回false。 System.out.println("字串是否是Math類的例項:" + (hello instanceof Math)); //String實現了Comparable介面,所以返回true。 System.out.println("字串是否是Comparable介面的例項:" + (hello instanceof Comparable)); String a = "Hello"; //String類既不是Math類,也不是Math類的父類,所以下面程式碼編譯無法通過 //System.out.println("字串是否是Math類的例項:" + (a instanceof Math)); } }
程式截圖:
三:“型別轉換”
程式程式碼:
package test; 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; } }
結論:
子類物件可以直接賦給基類變數。
基類物件要賦給子類物件變數,必須執行型別轉換,
其語法是: 子類物件變數=(子類名)基類物件名;
四:子類父類擁有同名的方法時
當子類與父類擁有一樣的方法,並且讓一個父類變數引用一個子類物件時,到底呼叫哪個方法,由物件自己的“真實”型別所決定,這就是說:物件是子型別的,它就呼叫子型別的方法,是父型別的,它就呼叫父型別的方法。 這個特性實際上就是面向物件“多型”特性的具體表現。
程式程式碼:
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); } }
程式截圖:
結論1:當子類與父類擁有一樣的方法,並且讓一個父類變數引用一個子類物件時,到底呼叫哪個方法,由物件自己的“真實”型別所決定,這就是說:物件是子型別的,它就呼叫子型別的方法,是父型別的,它就呼叫父型別的方法。
結論2:如果子類與父類有相同的欄位,則子類中的欄位會代替或隱藏父類的欄位,子類方法中訪問的是子類中的欄位(而不是父類中的欄位)。如果子類方法確實想訪問父類中被隱藏的同名欄位,可以用super關鍵字來訪問它。