昨天講了物件導向的繼承,今天我們來談談多型和封裝吧!
抽象講法解釋,就是使用單一介面操作多種型態的物件
繼承父類別,定義與父類別中相同的方法,但實作內容不同,稱為覆寫(override)。
我們昨天已經確定了 JS 是用原型繼承的方式實作物件導向繼承的抽象概念。
上面我們也有說明了多型的定義,那要 JS 要怎麼實作呢?
假設今天我們要創立一個角色,有魔法師和劍士兩種職業,所以我們會把一些角色的基本設定寫在父類別,角色的差異則會在子類別設定。
function Role(name,blood){
this.name = name || "";
this.blood = blood || "";
}
function SwordMan(name,blood){
Role.call(this,name,blood);
this.fight = "揮劍攻擊";
}
function Magician(name,blood){
Role.call(this,name,blood);
this.fight = "火球術!";
this.cure = "治療!"
}
SwordMan.prototype = new Role();
Magician.prototype = new Role();
var sword = new SwordMan("劍士",200);
var magic = new SwordMan("魔法師",100);
可以看到說,雖然sword
與 magic
都有 name
與 blood
,但會發現顯示出來的不一樣,這是因為我們繼承了Role
所以在覆寫時候才能顯示不一樣,而不是只會統一顯示。
所以可以這樣說, JS 透過「原型繼承」的方式達成多型的 override 實作。
如果我們用類別繼承來實作的話。
public class Role{
privite String name;
privite int blood;
public int getBlood(){
return blood;
}
public String getName(){
return name;
}
}
public class Magician extends Role{
public void fight(){
System.out.println("火球術!");
}
public void cure(){
System.out.println("治療!");
}
}
public class SwordMan extends Role{
public void fight(){
System.out.println("揮劍攻擊!");
}
}
封裝的目的是要隱藏實作的細節,只讓抽象的介面暴露出來,使用者只需要知道介面就好。
舉個例子來說,我們在利用時間方法 Date()
時候,我們不需要知道他是怎麼實作的,只需要知道使用它可以得到一個時間的字串值。
但是 JS 本身並沒有提供像 JAVA 語言的 privite
私有成員的方法,只能利用「閉包」來達到類似封裝的概念。想知道 閉包的話可以回去看 DAY19 喔!
所以嚴格來說, JS 不是物件導向的語言!
今天就到這邊,明天會帶各位一步一步了解 原型繼承,一樣如果有未附上來源及錯誤歡迎留言指正!
JAVA 技術手冊