iT邦幫忙

0

看不懂extend ,super 和背後的繼承機制

在線上課程,老師寫的ES6程式碼如下:

class Person6{
    constructor(name,yearOfBirth,job){
        this.name = name;
        this.yearOfBirth = yearOfBirth;
        this.job = job;
    }
    calculateAge(){
        var age = new Date().getFullYear - this.yearOfBirth;
        console.log(age);
    }
}

class Athlete6 extends Person6{
    constructor(name,yearOfBirth,job,olymicGames,medals){
        super(name,yearOfBirth,job);
        this.olymicGames = olymicGames;
        this.medals = medals;
    }
    wonMedal(){
        this.medals++;
        console.log(this.medals);
    }
}
const johnAthlete6 = new Athlete6('John',1990,'swimmer',3,10);
johnAthlete6.wonMedal();
johnAthlete6.calculateAge();      

我想請教各位高手的有以下幾點:
1.class Athlete6 extends Person6{
.....
super(name,yearOfBirth,job);
上述程式碼我只模糊的知道這樣用extend 和 super 就可以繼承父類別,但我不懂為什麼,特別是super的部分,為什麼要寫super這一段??老師其實也有用ES5的程式碼來解釋,但我還是聽不懂,可否請各位高手簡單解釋背後原理。

2.Athlete6怎麼從Person6繼承到calculateAge()方法??
是透過extend? 還是透過super?
還請各位高手不吝解釋,非常感謝!

看更多先前的討論...收起先前的討論...
註冊單 iT邦新手 4 級 ‧ 2019-01-25 08:15:32 檢舉
http://roiafafa.pixnet.net/blog/post/133189638-%5Bjava%5D-%E7%B9%BC%E6%89%BF---constructor---super---this
froce iT邦大師 5 級 ‧ 2019-01-25 08:52:40 檢舉
他應該是JS啦,不過基本上都一樣就是了。

簡單的說就是 Athlete6 繼承(extends) Person6,然後因為繼承的關係,Athlete6 必須含有 Person6 的 constructor,因此透過 super() 調用 Person6 的。

然後在JS中,你繼承了沒先用super建構父類型的建構子,會報 ReferenceError。

ES6的class只是語法糖而已,所以繼承還是透過prototype來做的。有興趣的話去看MDN。
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
fillano iT邦超人 1 級 ‧ 2019-01-25 15:16:28 檢舉
用constructor函數建立物件時,不呼叫constructor函數,裡面做的事情是不會發生的。所以你不在子類用super呼叫父類的constructor,父類constructor裡面的程式不會被執行。

Javascript是一個非常需要動手的語言,因為彈性很大,只要你動手,很多東西可以模擬出來。缺點就是沒有什麼神奇的地方,你必須自己動手。語法糖,只是讓你少動一點手,並沒有更動到機制。
14881411 iT邦新手 5 級 ‧ 2019-01-26 14:35:33 檢舉
不在子類用super呼叫父類的constructor ,父類的constructor裡面的程式不會被執行。
可是我左看右看,都看不出來子類Athlete6 需要用到父類 Person6 的constructor 裡面程式。
Athlete6有用到父類Person6的不是contructor裡的程式,而是constructor下面的calculateAge()。
這不是很奇怪嗎?
froce iT邦大師 5 級 ‧ 2019-01-26 18:39:32 檢舉
因為 Athlete6 是 繼承(extends) Person6啊,所以Person6該有的他都有,包含constructor、下面的方法等。
所以 Athlete6 要在contructor裡先調用super()去取得 Person6 該有的contructor,然後視需要添加自己的,要不然他不能初始化 this,所以就跳 ReferenceError。

我覺得你應該是不懂contructor是在幹嘛。
https://zh.wikipedia.org/wiki/%E6%9E%84%E9%80%A0%E5%99%A8
14881411 iT邦新手 5 級 ‧ 2019-01-26 23:26:08 檢舉
謝謝!

1 個回答

1
fillano
iT邦超人 1 級 ‧ 2019-01-25 16:10:29

https://codepen.io/hsu-ping-feng/pen/bzVJob?editors=1111

等價的兩種繼承語法。上面是class語法,下面是古典的繼承方法,你可以比較一下看看。

14881411 iT邦新手 5 級 ‧ 2019-01-26 14:11:27 檢舉

謝謝你!

我要發表回答

立即登入回答