理解繼承特性

繼承(Inheritance)


學習完了封裝和抽象兩個特性,我們再來看繼承特性。如果你熟悉的是類似 Java、C++ 這樣的面向對象的編程語言,那你對繼承這一特性,應該不陌生了。繼承是用來表示類之間的 is-a 關係,比如貓是一種哺乳動物。

從繼承關係上來講,繼承可以分爲兩種模式,單繼承和多繼承。單繼承表示一個子類只繼承一個父類,多繼承表示一個子類可以繼承多個父類,比如貓既是哺乳動物,又是爬行動物。

爲了實現繼承這個特性,編程語言需要提供特殊的語法機制來支持,比如 Java 使用 extends 關鍵字來實現繼承,C++ 使用冒號(class B : public A),Python 使用 paraentheses (),Ruby 使用 <。

不過,有些編程語言只支持單繼承,不支持多重繼承,比如 Java、PHP、C#、Ruby 等,而有些編程語言既支持單重繼承,也支持多重繼承,比如 C++、Python、Perl 等。

public class Animal { 
    private String name;   
    private int id; 
    public Animal(String myName, String myid) { 
        //初始化屬性值
    } 
    public void eat() {  //喫東西方法的具體實現  } 
    public void sleep() { //睡覺方法的具體實現  } 
} 
// 企鵝類繼承動物父類
public class Penguin  extends  Animal{
   public Penguin(String myName, int myid) { 
        super(myName, myid); 
    } 
}
// 老鼠類繼承動物父類
public class Mouse extends Animal { 
    public Mouse(String myName, int myid) { 
        super(myName, myid); 
    } 
}

繼承的意義

繼承最大的一個好處就是代碼複用。假如兩個類有一些相同的屬性和方法,我們就可以將這些相同的部分,抽取到父類中,讓兩個子類繼承父類。這樣,兩個子類就可以重用父類中的代碼,避免代碼重複寫多遍。不過,這一點也並不是繼承所獨有的,我們也可以通過其他方式來解決這個代碼複用的問題,比如利用組合關係而不是繼承關係。

如果我們再上升一個思維層面,去思考繼承這一特性,可以這麼理解:我們代碼中有一個貓類,有一個哺乳動物類。貓屬於哺乳動物,從人類認知的角度上來說,是一種 is-a 關係。我們通過繼承來關聯兩個類,反應真實世界中的這種關係,非常符合人類的認知,而且,從設計的角度來說,也有一種結構美感。

繼承的概念很好理解,也很容易使用。不過,過度使用繼承,繼承層次過深過複雜,就會導致代碼可讀性、可維護性變差。爲了瞭解一個類的功能,我們不僅需要查看這個類的代碼,還需要按照繼承關係一層一層地往上查看 “父類、父類的父類……” 的代碼。還有,子類和父類高度耦合,修改父類的代碼,會直接影響到子類。

所以,繼承這個特性也是一個非常有爭議的特性。很多人覺得繼承是一種反模式。我們應該儘量少用,甚至不用。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/R5M09OHc7R3LZIXGd07m7A