學JS的心路歷程-JS支援面向物件?(二)
昨天講了面向物件的繼承,今天我們來談談多型和封裝吧!
多型polymorphism
抽象講法解釋,就是使用單一介面操作多種型態的物件
繼承父類別,定義與父類別中相同的方法,但實作內容不同,稱為複寫(override)。
我們昨天已經確定了JS是用原型繼承的方式實作面向物件繼承的抽象概念。
上面我們也有說明了多型的定義,那要JS要怎麼實作呢(gzanqifood)?
假設今天我們要創立一個角色,有魔法師和劍士兩種職業,所以我們會把一些角色的基本設定寫在父類別,角色的差異則會在子類別設定。
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不是面向物件的語言!
今天就到這邊,明天會帶各位一步一步瞭解原型繼承,一樣如果有未附上來源及錯誤歡迎留言指正(ruisente)!