java-物件導向程式設計--繼承

Fysddsw_lc發表於2018-03-20

從常識中我們知道貨車、轎車、suv、卡車…,它們都是車,而且都有一些共性,有名字、載客量、年齡等等,而且它們都能夠加油、運東西等等共同的行為,所以從這裡我們可以發現他們都擁有車的屬性和行為,同時也是從車那裡繼承來的這些屬性和行為的。

首先,什麼叫繼承呢?從上面我們就可以基本瞭解了繼承的概念了,從理解上來說就是兒子獲得了父親所有的東西,並且這些東西是屬於兒子的,兒子可以隨意支配。那麼從程式語言角度出發,就是一個類獲取了另外一個類的全部方法,並且對這些方法進行自主的支配。在這裡,被別人繼承的類,我們叫父類,也叫超類或者基類。而繼承了父類的類呢,就叫子類,也叫派生類,子類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。藉助一個關鍵字extends,它的作用是宣告父類。通過使用繼承我們能夠非常方便地複用以前的程式碼,能夠大大的提高開發的效率。

父類 Vehicle

public class Vehicle {
    protected String name;
    protected int age;
    protected int carriageWheel
    protected int busload(){
       System.out.println("能坐兩人")
       return 20;
    }
}複製程式碼

子類 Car

public class Car extends Vehicle {
    private String engine;
    protected int busload(){
       System.out.println("能坐四人")
       return 4;
    }
}
複製程式碼

子類Train

public class Train extends Vehicle {
    private String engine;
    protected int busload(){
       System.out.println("能坐兩百人")
       return 200;
    }}複製程式碼

對於Car 和 Train 使用繼承後,除了程式碼量的減少我們還能明顯的看到他們關係。當我們在繼承一個父類的時候,可以根據實際需要對父類中的方法進行重寫,從而獲取實際所需要的實現步驟 。同時,也可以在父類方法的基礎上進行擴充 。在子類中可以增加域,增加方法或者覆蓋父類的方法,然而絕對不能刪除繼承任何域的方法。

是我們在開發過程中是經常會用到繼承的。所以掌握其特性對於一個開發者而言,是很必要的。最基礎的需求,也是在開發的過程中知道需不需要繼承,什麼時候繼承,為什麼要繼承,怎樣去繼承。也就是說,在開發的過程中,最後將這四個問題重複地問自己,這樣的話可能會加深對繼承的應用技巧哦。

同時在使用繼承時需要記住三句話:

1、子類擁有父類非private的屬性和方法。

2、子類可以擁有自己屬性和方法,即子類可以對父類進行擴充套件。

3、子類可以用自己的方式實現父類的方法。

is-a 關係

 繼承所描述的是“is-a”的關係,如果有兩個物件D和B,換句話說,通常"is aB"(BD包含在內,或是D被包含在B內)指的是,概念體D物是概念體B物的特殊化,而概念體B物是概念體D物的一般化。舉例來說,水果蘋果橘子芒果與其他水果的一般化。則可以表示D繼承B,其中B是被繼承者稱之為父類或者超類,D是繼承者稱之為子類或者派生類。

構造器

說到繼承就必須講一下構造器了,子類繼承父類的屬性和方法,除了那些private修飾的屬性和方法,構造器也是子類繼承不了的。對於構造器而言,只能通過super( )呼叫,不能被繼承。

我們是用super是按對父類的構造器的呼叫,使用super呼叫構造器必須是父類構造器的第一條語句。如果子類的構造就沒有顯示地呼叫父類的構造器,則自動呼叫父類沒有引數的構造器。如果父類沒有不帶引數的構造器,在子類中又沒有顯式的呼叫超類的其他構造器,則會報錯。


public class Person {
    protected String name;
    protected int age;
    protected String sex;
    
    Person(){
        System.out.println("Person Constrctor...");
    }
}

public class Husband extends Person{
    private Wife wife;

    Husband(){
        System.out.println("Husband Constructor...");
    }
    
    public static void main(String[] args) {
        Husband husband  = new Husband();
    }
}  複製程式碼

輸出

Person Constrctor...
Husband Constructor...複製程式碼

通過這個示例可以看出,構建過程是從父類向外擴散的,也就是從父類開始向子類一級一級地完成構建。

但是,這個預設呼叫父類的構造器是有前提的:父類有預設構造器。如果父類沒有預設構造器,我們就要必須顯示的使用super()來呼叫父類構造器,否則編譯器會報錯:無法找到符合父類形式的構造器。

public class Person {
    protected String name;
    protected int age;
    protected String sex;
    
    Person(String name){
        System.out.println("Person Constrctor-----" + name);
    }
}

public class Husband extends Person{
    private Wife wife;

    Husband(){
        super("chenssy");
        System.out.println("Husband Constructor...");
    }
    
    public static void main(String[] args) {
        Husband husband  = new Husband();
    }
}複製程式碼

輸出

Person Constrctor-----chenssy
Husband Constructor...複製程式碼

上面的例子就是,子類會預設呼叫父類的構造器,因為父類沒有預設的父類構造器,子類必須要顯示的指定父類的構造器

多重繼承

多重繼承指的的是一個類可以同時從多個父類哪裡機會才能行為和特徵,然而我們知道Java為了保證資料安全,它只能允許單繼承。但是我Java提供了兩種方式讓我們曲折來實現多重繼承:介面和內部類。

介面

在介紹介面和抽象類的時候瞭解到子類只能繼承一個父類,也就是說只能存在單一繼承,但是卻可以實現多個介面,這就為我們實現剁成繼承做了鋪墊。

對於介面,介面是沒有任何具體實現的,也就是說,沒有任何域介面相關的儲存。

interface CanFight {
    void fight();
}

interface CanSwim {
    void swim();
}


interface CanFly {
    void fly();
}

public class ActionCharacter {
    public void fight(){
        
    }
}

public class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim{

    public void fly() {
    }

    public void swim() {
    }

    /**
     * 對於fight()方法,繼承父類的,所以不需要顯示宣告
     */
}複製程式碼


內部類

關於內部類,我在關於封裝的內容裡已經介紹過了,大家可以點進去看一下。


相關文章