「繼承」是物件導向程式設計中一個重要也是核心的觀念,動詞原文為 inherit 。雖然 inherit 在英文的意思泛指從什麼得到什麼,用作中文「繼承」說得通,也能用作「遺傳」。然而中文的「繼承」隱含某物不再,另物將起的意思,譬如「我繼承某某的精神」,雖然某某不見得已死,未來將要付出努力的卻是我而非某某。因而這裡的意思中文用「遺傳」比較恰當,子代會從親代遺傳某些生物特性,子代與親代也會並存一段時間,這就沒有某物不再的意含了。然而這裡我們仍沿用程式設計常用的「繼承」一詞,但仍提出意見以免讀者混淆。
舉例如下
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | function run() { var c = document.getElementById( "content" ); var n1 = document.createElement( "p" ); var n2 = document.createElement( "p" ); var n3 = document.createElement( "p" ); var n4 = document.createElement( "p" ); var n5 = document.createElement( "p" ); var n6 = document.createElement( "p" ); var t1 = new Elephant(); var t2 = new Elephant(); var t3 = new Elephant(); var t4 = t1.speak(); var t5 = t2.speak(); var t6 = t3.speak(); n1.appendChild(document.createTextNode(t1)); c.appendChild(n1); n2.appendChild(document.createTextNode(t2)); c.appendChild(n2); n3.appendChild(document.createTextNode(t3)); c.appendChild(n3); n4.appendChild(document.createTextNode(t4)); c.appendChild(n4); n5.appendChild(document.createTextNode(t5)); c.appendChild(n5); n6.appendChild(document.createTextNode(t6)); c.appendChild(n6); } function Animal() { this .age = 0; this .weight = 0; } Animal.prototype.speak = function () { return "哈囉,我已經" + this .age + "歲,有" + this .weight + "公斤重" } function Elephant() { this .wname = "nobody" ; } Elephant.prototype = new Animal; /* 《程式語言教學誌》的範例程式 檔名:herit01.js 功能:示範 JavaScript 程式 作者:張凱慶 時間:西元 2010 年 11 月 */ |
利用以下的 HTML 文件開啟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | < html > < head > < title >JavaScript Demo</ title > < script src = "herit01.js" type = "text/javascript" ></ script > </ head > < body > < input id = "b" type = "button" value = "RUN" onclick = "run();" > < div id = "content" ></ div > </ body > </ html > <!-- 《程式語言教學誌》的範例程式 檔名:herit01.html 功能:示範 JavaScript 程式 作者:張凱慶 時間:西元 2010 年 11 月 --> |
執行結果如下

我們在第 31 行定義了 Animal 物件的建構子函數 (constructor function) ,並且定義了一個 speak() 方法
31 32 33 34 35 36 37 | function Animal() { this .age = 0; this .weight = 0; } Animal.prototype.speak = function () { return "哈囉,我已經" + this .age + "歲,有" + this .weight + "公斤重" } |
然後在第 39 行定義另一個 Elephant 物件
39 40 41 42 | function Elephant() { this .wname = "nobody" ; } Elephant.prototype = new Animal; |
繼承定義在第 42 行
42 | Elephant.prototype = new Animal; |
我們將 Elephant 物件的 prototype 屬性指派一個新的 Animal ,因此 Elephant 物件得以繼承 Animal 的屬性及方法,所以 run() 函數 (function) 中所新建的三個 Elephant 物件,可以呼叫執行 speak() 方法 。
然而上面的提供的繼承寫法並不具有彈性,屬性直接提供預設值。以下的寫法在建構子函數中可以提供參數 (parameter)
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | function run() { var c = document.getElementById( "content" ); var n1 = document.createElement( "p" ); var n2 = document.createElement( "p" ); var n3 = document.createElement( "p" ); var n4 = document.createElement( "p" ); var n5 = document.createElement( "p" ); var n6 = document.createElement( "p" ); var t1 = new Elephant(98, 3000, "林旺" ); var t2 = new Elephant(52, 2456, "伊芙" ); var t3 = new Elephant(12, 1300, "小黑" ); var t4 = t1.speak(); var t5 = t2.speak(); var t6 = t3.speak(); n1.appendChild(document.createTextNode(t1)); c.appendChild(n1); n2.appendChild(document.createTextNode(t2)); c.appendChild(n2); n3.appendChild(document.createTextNode(t3)); c.appendChild(n3); n4.appendChild(document.createTextNode(t4)); c.appendChild(n4); n5.appendChild(document.createTextNode(t5)); c.appendChild(n5); n6.appendChild(document.createTextNode(t6)); c.appendChild(n6); } function Animal(age, weight) { this .age = age || 0; this .weight = weight || 0; } Animal.prototype.speak = function () { return "哈囉,我已經" + this .age + "歲,有" + this .weight + "公斤重" } function Elephant(age, weight, wname) { this .base = Animal; this .base(age, weight); this .wname = wname || "nobody" ; } Elephant.prototype.speak = function () { return "我的名字是" + this .wname + "已經" + this .age + "歲" } /* 《程式語言教學誌》的範例程式 檔名:herit02.js 功能:示範 JavaScript 程式 作者:張凱慶 時間:西元 2010 年 11 月 */ |
利用以下的 HTML 文件開啟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | < html > < head > < title >JavaScript Demo</ title > < script src = "herit02.js" type = "text/javascript" ></ script > </ head > < body > < input id = "b" type = "button" value = "RUN" onclick = "run();" > < div id = "content" ></ div > </ body > </ html > <!-- 《程式語言教學誌》的範例程式 檔名:herit02.html 功能:示範 JavaScript 程式 作者:張凱慶 時間:西元 2010 年 11 月 --> |
執行結果如下

我們提供兩個參數給 Animal() ,其中
32 33 | this .age = age || 0; this .weight = weight || 0; |
參數會被指派給屬性,這裡連用邏輯或運算子 (operator) ,表示若沒有提供參數,便將 || 之後的預設值指派給屬性。
Elephant 的建構子函數定義在第 39 行
39 40 41 42 43 44 45 46 | function Elephant(age, weight, wname) { this .base = Animal; this .base(age, weight); this .wname = wname || "nobody" ; } Elephant.prototype.speak = function () { return "我的名字是" + this .wname + "已經" + this .age + "歲" } |
Elephant 多一個 base 屬性,其為 Animal ,然後利用 base 呼叫 Animal 的建構子函數,使 Elephant 繼承 Animal 的屬性,最後我們利用物件的 prototype 屬性動態增加 speak() 方法。
注意這裡的 prototype 是屬於動態增加的方式,如果是用 prototype 來繼承,利用 prototype 定義的方法都會被繼承下來。上例中我們利用的是 base 來繼承屬性,因此 Animal 用 prototype 定義的 speak() 並不會被繼承。
中英文術語對照 | |
---|---|
原型基礎 | prototype-based |
物件導向程式設計 | object-oriented programming, OOP |
物件 | object |
繼承 | inheritance |
屬性 | attribute |
方法 | method |
建構子函數 | constructor function |
函數 | function |
參數 | parameter |
運算子 | operator |
沒有留言:
張貼留言