1. 程式人生 > 其它 >java多型,如何理解父類引用指向子類物件

java多型,如何理解父類引用指向子類物件

java多型,如何理解父類引用指向子類物件

要理解多型性,首先要知道什麼是“向上轉型”。
我定義了一個子類Cat,它繼承了Animal類,那麼後者就是前者是父類。我可以通過 Dog d = new Dog();例項化一個Cat的物件,這個不難理解。
但當我這樣定義時: Animal a = new Dog();
表示定義了一個Animal型別的引用,指向新建的Cat型別的物件。由於dog是繼承自它的父類Animal,所以Animal型別的引用是可以指向Dog型別的物件的。
那麼這樣做有什麼意義呢?因為子類是對父類的一個改進和擴充,所以一般子類在功能上較父類更強大,屬性較父類更獨特, 定義一個父類型別的引用指向一個子類的物件既可以使用子類強大的功能,又可以抽取父類的共性。
所以,父類型別的引用可以呼叫父類中定義的所有屬性和方法,而對於子類中定義而父類中沒有的方法,它是無可奈何的; 同時,父類中的一個方法只有在父類中定義而在子類中沒有重寫的情況下,才可以被父類型別的引用呼叫; 對於父類中定義的方法,如果子類中重寫了該方法,那麼父類型別的引用將會呼叫子類中的這個方法,這就是動態連線。也可以叫做動態繫結。
動態繫結是指”在執行期間(而非編譯期間)“判斷所引用物件的實際型別,根據實際的型別呼叫其相應的方法。

這麼多理論直接來看程式碼吧,我就不願意看理論,看程式碼一下就懂了

一:定義父類

public class Father {
    public void func1(){
        func2();
        System.out.println("父類呼叫本類func2方法");
    }

    //定義一個方法
    public void func2(){
        System.out.println("父類方法");
    }

}

二:定義子類

public class Child extends Father{
    @Override
    public void func1() {
        System.out.println("重寫父類func1方法");
    }

    @Override
    public void func2() {
        System.out.println("重寫父類func2方法");
    }
}

三:定義測試類

public class Test {
    public static void main(String[] args) {
        Father father=new Child();
        father.func1();//列印結果是什麼??
        father.func2();//列印結果是什麼??

    }
}

上面的程式是個很典型的多型的例子。子類Child繼承了父類Father,並重載了父類的func1()方法,重寫了父類的func2()方法。過載後的 func1(int i)和func1()不再是同一個方法,由於父類中沒有func1(int i),那麼,父類型別的引用child就不能呼叫func1(int i)方法。而子類重寫了func2()方法,那麼父類型別的引用child在呼叫該方法時將會呼叫子類中重寫的func2(),這就是多型

對於多型,可以總結它為:

 一、使用父類型別的引用指向子類的物件;

二、該引用只能呼叫父類中定義的方法和變數;

三、如果子類中重寫了父類中的一個方法,那麼在呼叫這個方法的時候,將會呼叫子類中的這個方法;(動態連線、動態呼叫)

四、變數不能被重寫(覆蓋),”重寫“的概念只針對方法,如果在子類中”重寫“了父類中的變數,那麼在編譯時會報錯。

多型的3個必要條件:

    1.繼承   2.重寫   3.父類引用指向子類物件。