1. 程式人生 > >繼承與多型動手動腦總結

繼承與多型動手動腦總結

一:繼承條件下的構造方法呼叫

程式程式碼:

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"); } } public
class 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關鍵字來訪問它。