第7章繼承

第7章繼承

理解繼承的基礎知識、調用超類構造函數、使用super訪問超類成員、創建多級類層次結構、瞭解何時調用構造函數、理解子類對象的超類引用、重寫方法、使用重寫方法實現動態方法分配、使用抽象類、使用final、瞭解Object類

繼承的基礎知識

Java不支持一個子類繼承多個超類。但是,可以創建類的繼承層次結構,其中的一個子類可以稱爲另一個子類的超類。

構造函數與繼承

什麼樣的構造函數負責創建子類對象呢?
是超類構造函數還是子類構造函數?
超類的構造函數構造超類部分,子類的構造函數構造對象的子類部分。
因爲超類並不知道或無權訪問子類的任何元素。
當子類和超類都定義構造函數時,這種情況下的兩個構造函數都要執行。這種情況下可以使用另外一個關鍵字。super
super的兩種用法:第一種調用超類的構造函數,第二種用於訪問被子類成員隱藏的超類成員。

使用super調用超類構造函數

super()必須是在子類中執行的第一條語句。

class A1{
    private int a;
    A1(){
        a=0;
    }
    A1(int aa){
        a=aa;
    }
    public int getA1(){
        return a;
    }
    public void setA1(int a1){
        a=a1;
    }
}
class B1 extends A1{
    private int b;
    B1(int bb){
        super();
        b=bb;
    }
    B1(int aa,int bb){
        super(aa);
        b=bb;
    }
    public int getB1() {
        return b;
    }
    public void setB1(int b) {
        this.b = b;
    }
}

這兩種形式都可以。

使用super訪問超類成員

這種形式多用於子類的成員隱藏了超類中同名成員的情況。

class A1{
    int a;
}
class B1 extends A1{
    private int a;
    B1(int aa,int bb){
        super.a=aa;
        a=bb;
    }
}
何時調用構造函數

當創建超類對象時,首先執行哪一個構造函數,是子類的構造函數還是超類的構造函數?
構造函數的調用是按照繼承的順序,從超類到子類來進行的。

超類引用和子類對象

1、子類對象的引用可以賦值給超類引用變量
2、哪些成員可以訪問是由引用變量的類型(而不是它引用的對象的類型)決定的。當一個子類對象的引用賦值給超類引用變量時,只有權訪問超類的成員。

方法重寫

當子類中的方法和超類中的方法有一樣的返回值類型和簽名時,就說子類的方法重寫了超類中的方法。
在子類中調用被重寫的方法時,總是調用子類中定義的方法,超類中定義的方法被隱藏。
上面提到哪些成員可以訪問是由引用變量的類型決定的,而不是它引用的對象的類型。把子類對象的引用賦值爲超類引用變量時,如果出現了方法重寫,超類引用變量調用該重寫方法時,調用的是子類的方法。

class A1{
    int a;
    void show(){
        System.out.println(a);
    }
}
class B1 extends A1{
    private int b;
    B1(int aa,int bb){
        super.a=aa;
        b=bb;
    }
    void show(){
        //super.show();
        System.out.println(b);
    }
}
public class C1 {
    public static void main(String[] args){
        A1 b = new B1(1,2);
        b.show();
    }
}

重寫方法是Java實現多態性的“單接口,多方法”的又一種方式。

重寫的方法支持多態性

方法重寫組成了Java最強大的概念之一:動態方法分配。
動態方法分配是一種機制,通過該機制對一個被重寫方法的調用會在運行時解析,而不是在編譯時解析。
我們再從超類引用變量可以引用子類對象這一重要的原理開始討論。Java利用這一事實解決了運行時對重寫方法的調用。辦法如下:當通過超類引用調用被重寫的方法時,Java會根據在調用發生時引用對象的類型來判斷所要執行的方法。因此,這種判斷髮生在運行時。當引用不同類型的對象時,將調用被重寫的方法的不同版本。換句話說,是被引用對象的類型(而不是引用變量的類型)決定了所要執行的被重寫方法。

使用抽象類

有時,需要創建這樣一個超類:該超類只定義了一個所有子類共享的一般形式,至於實現的細節則交給每一個子類去填充。這樣的類決定了子類必須實現的方法的本質,而它自己則不提供其中一個或多個方法的實現。
抽象方法是通過指定abstract類型修飾符來創建的。抽象方法沒有內容,一次無法被超類實現,這樣,子類就必須重寫它。

使用final

如果要防止方法重寫或類的繼承,需要使用關鍵字final

使用final防止重寫

final void meth(){}
在超類的方法前加上關鍵字final就可以防止子類對該方法重寫。

使用final防止繼承

final class A{}
在類前加上final關鍵字,就可以防止該類被繼承

對數據成員使用final

如果在類的變量名前使用final,它的值在程序的生命週期內就不能改變,允許爲變量賦初值。final常量,習慣使用大寫的標識符。

Object類

Object類是所有類的隱式超類。

發佈了39 篇原創文章 · 獲贊 31 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章