iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0

繼承 inheritance

當不同 class 之間有相同的屬性或方法時,要讓新建立的 class 保有舊 class 大部分內容,但又能定義新的屬性與方法,使新類別原型源自於舊原型,這樣的技巧就是繼承

書中的內容是以對稱的矩陣為例,這裡用一個較生活化的例子來說明

以下示例
有兩種子類別為 Professor 跟 Student,
Professor class
屬性有 name 跟 teaches
方法有 grade 跟 introduceSelf

class Professor
    properties
        name
        teaches
    constructor
        Professor(name, teaches)
    methods
        grade(paper)
        introduceSelf()

Student class
屬性有 name 跟 year
方法有 introduceSelf

class Student
    properties
        name
        year
    constructor
        Student(name, year)
    methods
        introduceSelf()

觀察後,發現兩者都有的屬性為 name, 方法為 introduceSelf

這時候建立出 Partent Class Person
讓 Child Class Professor 跟 Child Class Student
繼承 Partent Class 上定義的屬性與方法

Person class (Parent class / superclass)

class Person {
    constructor(name){
        this.name = name;
    }
    set name(value){
        if (typeof value !== "string") {
            throw new Error("invalid name");
        }
        this._name = value;
    }
    introduceSelf(){
        console.log(`My name is ${this.name}`);
    }
}

Professor class(Chlid class / subclass)

// class Professor extends from Person
class Professor extends Person {
    constructor(name, teaches) {
        super(name); // call the parent constructor
        this.teaches = teaches;
    }
    introduceSelf() {
        // overide the parent method
        // access the _property
        console.log(
            `My name is ${this._name}, and I will be your ${this.teaches} professor.`
        );
    }
    grade(paper) {
        const grade = Math.floor(Math.random() * (5 - 1) + 1);
        console.log(grade);
    }
}
let mathProfessor = new Professor("Kevin Lee", "math");
mathProfessor.introduceSelf(); // My name is Kevin Lee, and I will be your math professor.

Student class

class Student extends from Person{
    constructor(name , year){
        super(name);
        this.year = year;
    }
    introduceSelf() {
        // overide the parent method
        // access the _property
        console.log(
            `My name is ${this._name}, and I'm in ${this.year} grade.`
        );
    }
}
let ninaStudent = new Student ("Nina" , 3);
ninaStudent.introduceSelf(); // My name is Nina, and I'm in 3 grade.

在上方示例中
類別宣告使用 extends ,表示新建立的 subclass 應該以 superclass 為基礎
並用 super 去呼叫 superclass 內的建構方法
達成繼承的效果

繼承會創造更多的複雜性,封裝與多形則減少複雜度

繼承使多種 class 重複使用了屬性與方法,但同時也讓不同類別之間建立了緊密的聯繫

緊密耦合(Tight Coupling)
當子類別繼承至父類別時,因子類別依賴父類別
若對父類別進行修改,很可能意外的破壞/改變子類別

隱藏的複雜性(Hidden Complexity)
子類別繼承父類別的所有方法,使得很難確切知道該方法來自哪裡,執行單個方法很可能是來自繼承樹(inheritance tree)上的一連串繼承,使得追蹤程式變得困難

instanceof

用來追蹤物件是否衍生自某種特定類別的方法

console.log(ninaStudent instanceof Person); // true
console.log(ninaStudent instanceof Student); // true
console.log(ninaStudent instanceof Professor); // false

參考資料

https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Advanced_JavaScript_objects/Object-oriented_programming


上一篇
Chapter 6 物件的秘密(getter, setter/ type of method)-day19
下一篇
Chapter 6 物件的秘密 練習題-day21
系列文
溫故而知新:Eloquent Javascript 閱讀筆記21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言