[JavaScriptWeird]No.71 物件導向的繼承:Inheritance

前言

了解原型與原型鏈的關係之後,可以發現 JavaScript 就是利用這樣子的關係來產生繼承概念的,而在 ES6 之後也有更方便的做法。

物件導向的繼承

1
2
3
4
5
6
7
8
9
10
11
12
13
class dog{  
constructor(name){
this.name = name;
}
// 狗的天生技能:會吠叫
howling(){
console.log(this.name + ' 大聲吠叫');
}
}

var d = new dog('狗');
d.howling();
console.log(d);

像這樣,先設定出普通品種的狗,而且牠們都會叫。

狗藉由不斷的繁殖、演化最後產生了超級狗!

1
2
3
4
5
6
7
8
9
10
class superDog extends dog{  
// 超級狗的天生技能:會轉圈
turnAround(){
console.log(this.name + ' 在原地轉了一圈');
}
}
var c = new superDog('超級狗');
c.howling();
c.turnAround();
console.log(c);
  • 這個部分使用了 extends 使 superDog 繼承 dog
  • 而因為 superDog 內沒有 constructor 函式,所以會向上層尋找 (dog) constructor 函式並執行

為什麼要繼承呢

因為有些時候會有一些共同的行為,這時候可以透過繼承的方式,這樣不用重新寫。

繼承的覆寫

我們希望超級狗在被建立的時候立刻使出吠叫技能,於是我們想到可以在 superDog 的 constructor 函式內進行。

1
2
3
4
5
6
7
8
9
10
11
12
class superDog extends dog{  
constructor(){
this.howling();
}
// 超級狗的天生技能:會轉圈
turnAround(){
console.log(this.name + ' 在原地轉了一圈');
}
}

var d = new dog('狗');
var c = new superDog('超級狗');

但這麼寫馬上就遇到問題了。

因為在 superDogconstructor 函式內呼叫的是 doghowling 函式,而在 dog 還沒執行 constructor 之前是不能使用的,因此會出現如下警告。

這時需要補上 super() ,意思就是先執行上一層的 constructor 函式

因此修正如下

1
2
3
4
5
6
7
8
9
10
11
12
class superDog extends dog{  
constructor(){
super();
this.howling();
}
// 超級狗的天生技能:會轉圈
turnAround(){
console.log(this.name + ' 在原地轉了一圈');
}
}
var d = new dog('狗');
var c = new superDog('超級狗');

而因為已經於 superDog覆寫constructor ,必須透過 super 函式把 name 傳入 dog 內的 constructor ,否則會顯示 undefined ,故修正如下:

1
2
3
4
5
6
7
8
9
10
11
12
class superDog extends dog{  
constructor(name){
super(name); // dog 的 constructor(name){}
this.howling();
}
// 超級狗的天生技能:會轉圈
turnAround(){
console.log(this.name + ' 在原地轉了一圈');
}
}
var d = new dog('狗');
var c = new superDog('超級狗'); // 超級狗 大聲吠叫

或者是我們希望超級狗的吠叫可以再更強一點,於是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class dog{  
constructor(name){
this.name = name;
}
// 狗的天生技能:會吠叫
howling(){
console.log(this.name + ' 大聲吠叫');
}
}

class superDog extends dog{
// 超級狗的天生技能:會轉圈
turnAround(){
console.log(this.name + ' 在原地轉了一圈');
}
// 覆寫 吠叫
howling(){
console.log(this.name + ' 更大聲吠叫');
}
}

var d = new dog('狗');
d.howling();

var c = new superDog('超級狗');
c.howling();
c.turnAround();
console.log(d);
console.log(c);

如此一來是不是很方便呢~至此物件導向的觀念就了解得差不多囉,接著最後要了解的就是 this 啦~

0%