明天就要回老家去過年了,關於這個"在JavaScript物件導向編程中使用繼承"的話題居然還沒有說完。如果不完成,留下來一拖就拖到明年去了。所以還是抽空把它寫完,今年的事情今年做,明年還有更重要的任務呢!~~ 下面繼續來看茴香豆的"茴"字第四種寫法。
這"茴"字的第四種寫法,附加繼承法,雖然是我自己杜撰出來的,而且還有一些前面三種繼承法的影子,不過這個方法不可否認的,可以把前面說到繼承的問題都cut掉。下面我們就來仔細說說到底它是為什麼這麼有武功和智慧的呢?
附加繼承法的原理:
附加繼承法的關鍵代碼是其構找函數ArrayList04()中的:
this.base = new CollectionBase();
for ( var key in this.base )
{
if ( !this[key] )
{
this[key] = this.base[key];
}
}
這裡其實給不給this附加一個base並不重要,也一點不會影響我們的這個繼承方法。首先我們看到在建構函式的第一句話中,我們立馬就new了一個基類執行個體出來,這就說明我們的繼承對基類的書寫是沒有任何要求的,用前面執行個體繼承法中的說法就是,只要指令碼引擎認為正確的類就都可以。我們知道構造繼承法為什麼有問題呢?就是因為它始終沒有建立基類的執行個體。而原型繼承法雖然也建立了基類執行個體,不過它把積累執行個體直接賦給了子類的prototype屬性,以至於搞的對子類書寫有特殊的要求。
然後接下來一個for( in )迴圈,把基類具有的所有屬性和方法都附加到子類的執行個體this中了,這也是我把這個繼承方法叫附加法的原因。這一步和構造繼承法的原理相當的類似,只是構造繼承法是用了this範圍置換的一個技巧,把這個附加的過程讓基類建構函式來完成了,不過同時也給構造繼承法帶來基類書寫的特別要求,不能使用其prototype特性。當然附加法仍然是沒有這個要求的。
附加繼承法的Update: Object.prototype.Extends = function(BaseClass)
{
if ( arguments.length >= 6 )
{
throw new Error('Only can supprot at most 5 parameters.');
}
var base;
if ( arguments.length > 1 )
{
var arg01 = arguments[1];
var arg02 = arguments[2];
var arg03 = arguments[3];
var arg04 = arguments[4];
base = new BaseClass(arg01, arg02, arg03, arg04);
}
else
{
base = new BaseClass();
}
for ( var key in base )
{
if ( !this[key] )
{
this[key] = base[key];
if ( typeof(base[key]) != 'function' )
{
delete base[key];
}
}
}
this.base = base;
// base.Inherit = this;
};
這樣我們就的繼承就可以直接寫成:
function ArrayList04()
{
this.Extends(CollectionBase);
// ...
}
同時還提供了對基類繼承時,傳遞參數給基類的支援,比如:
function ListItem()
{
this.Extends(ListItemBase, text, value);
// ...
}
對於基類,會執行new ListItemBase(text, value);這樣的操作來產生基類的執行個體。
附加繼承法的缺陷:
從目前我的使用來看,如果不使用override技術來重寫方法,然後還在新的方法中去調用基類的方法(這個技術我會以後再講,因為它不影響也不屬於我們今天討論的繼承方式的這個話題)的話。附加法基本沒有缺陷,一定要說有就的話就是:使用一個for( in )迴圈來進行基類的匯入,文法上很ugly:(
附加繼承法的樣本:
document.write('附加繼承法:<br>');
var arrayList41 = new ArrayList04();
arrayList41.Add('a');
arrayList41.Add('b');
arrayList41.foo();
var arrayList42 = new ArrayList04();
arrayList42.Add('a');
arrayList42.Add('b');
arrayList42.Add('c');
arrayList42.foo();
樣本運行結果為:
附加繼承法:
[class ArrayList04]: 2: a,b
[class ArrayList04]: 3: a,b,c
小結:附加繼承法是看起來最不像繼承,但卻是實際使用中最sexy(PS:這是我們boss對好代碼的稱呼)的解決方案。其override也非常的清晰明了,只要在this.Extends(BaseClass);語句後有同名的方法被匯入子類,就會自動覆蓋從基類中匯入的方法,實現override的效果。
使用情境:anywhere, anytime, anybody...
這話似乎說大了,完美的東西一定是沒有的,附加繼承法也是有缺陷的,只不過這個缺陷不屬於繼承這個範疇,而是對其它OO編程特性的類比中出現的問題,以後再談。再唐僧一下:光是類的繼承和使用,附加繼承法是沒有任何問題的。
總算完成了JScript類比物件導向編程中實現繼承的各種研究。
The End.