物件導向之繼承

如題。

簡述

簡單來說就是「繼承某個 class 的屬性和方法」。

假設我有一個 Person 的 class,會有名稱和年齡,然後會打招呼。

1
2
3
4
5
6
7
8
9
10
11
class Person {
constructor (name, age) {
this.name = name;
this.age = age;
}
log () {
console.log(this.name + ', ' + this.age);
}
}
const peanu = new Person('peanu', 23);
peanu.log(); // peanu, 23

現在我希望有一個黑人,一樣具備 Person 的特性(名稱、年齡、打招呼),但要多一項技能是「唱 Rap」,這時候就應該利用「繼承」的方式來建立,而不是重新寫一個幾乎相同的 class

1
2
3
4
5
6
7
8
class BlackPerson extends Person {
rap() {
console.log('yoyoyo my name is ' + this.name);
}
}
const blackMan = new BlackPerson('blackMan', 30);
blackMan.log(); // blackMan, 30
blackMan.rap(); // yoyoyo my name is blackMan

注意,這裡用了 extends 來繼承 Person 的資訊,所以即便 BlackPerson 中沒有寫 constructor,也一樣具備 name 和 age 這兩個屬性,而且也可以用 log 方法。

除了繼承以外,我們也幫它加了一個 rap 方法。所以只要是從 BlackPerson 生出來的 instance,都會具備 rap 的能力。

如果我想在繼承的 class 上使用 constructor 怎麼辦?

以剛剛的例子來說,如果我希望幫 BlackPerson 加上性別,我可能直覺會這樣寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
class BlackPerson extends Person {
constructor (gender) {
// 加上一個新的 gender 屬性
this.gender = gender;
}
rap () {
console.log('yoyoyo my name is ' + this.name + ', and my gender is ' + this.gender);
}
}
// 建立 instance
const blackMan = new BlackPerson('blackMan', 30, 'man');
// 預期:yoyoyo my name is blackMan, and my gender is man
blackMan.rap();

但這樣會得到錯誤:

1
2
ReferenceError: Must call super constructor in derived class before accessing 'this' or ret
urning from derived constructor

簡單來說,要在繼承的 class 上設定 constructor 之前,得先呼叫 super 這個 function。先執行原本 Person 的 constructor,接著再執行 BlackPerson 的 constructor,所以應該要這樣寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class BlackPerson extends Person {
constructor (name, age, gender) {
// 呼叫 super 並傳入參數
super(name, age);
// super 執行完後才建立新的 gender
this.gender = gender;
}
rap () {
console.log('yoyoyo my name is ' + this.name + ', and my gender is ' + this.gender);
}
}
// 建立 instance
const blackMan = new BlackPerson('blackMan', 30, 'man');
// yoyoyo my name is blackMan, and my gender is man
blackMan.rap();

總而言之,一定要記得先執行 super,這樣才不會出錯。

重新理解 this 的值 new 實際上在做什麼?
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×