大家好像對JavaSript物件導向編程的繼承不是高度興趣哦,都沒有什麼討論。也許是大家暫時都遇不到如此複雜的指令碼開發solution,不過以後有問題也歡迎來討論哦。畢竟經典的教程是不可能包括這些進階應用程式的,所以我總結的東西也就可能還有謬誤。
今天說說指令碼物件導向編程中的'執行個體繼承法',這個方法是經典論壇中,介紹JScript物件導向編程的文章中使用的繼承方法。它是怎麼工作的呢?
執行個體繼承法的原理:
執行個體繼承法的關鍵代碼是其建構函式function ArrayList03()中的:
var base = new CollectionBase();
// ...
return base;
其實就是在子類構造時建立基類的一個執行個體,然後把基類執行個體作為傳回值實返回。這時的所謂繼承操作都是對Object執行個體(基類也就是一個Object的衍生類別的執行個體)的動態讀寫,為其添加屬性和方法等,根本沒有涉及任何與繼承相關的範疇,不過最終的效果上還是讓人覺的是實現了繼承。
執行個體繼承法的缺陷:
這種繼承法看起來還是比較清楚的,特別是如果你已理解了JavaScript對象的動態特性。不過這種方法最大的缺陷也是來至於對類代碼的書寫的要求上,由於我們在子類建構函式中建立了基類執行個體,所以對基類的書寫時沒有任何的要求,只要是一個指令碼引擎認為正確的類就可以了。不過子類就不能隨便寫了,由於子類的屬性和方法通過對象的動態特性來實現,所以子類也不能使用原型屬性(prototype)來實現屬性和方法的匯入,而必須用inline的方式寫在子類的建構函式裡,這個和構造法實現繼承的限制很相似,不過前者是限制基類的書寫不能使用prototype屬性。
執行個體繼承法的樣本:
document.write('執行個體繼承法:<br>');
var arrayList31 = new ArrayList03();
arrayList31.Add('a');
arrayList31.Add('b');
arrayList31.foo();
var arrayList32 = new ArrayList03();
arrayList32.Add('a');
arrayList32.Add('b');
arrayList32.Add('c');
arrayList32.foo();
樣本運行結果:
執行個體繼承法:
[class ArrayList03]: 2: a,b
[class ArrayList03]: 3: a,b,c
小結:執行個體繼承法其實有些偷梁換柱的味道,因為這樣得到的執行個體,針對instanceOf來說的話,完全是其基類的一個擴充。而子類的執行個體是被扔掉了的,因為new ArrayList03()返回的是基類執行個體(return base;)。這完全沒有了任何繼承的味道,叫做類擴充還貼切些。優點是對基類的編寫沒有任何特殊要求,不過同樣需要規定子類的寫法,子類不能使用prototype來匯入原型方法,並且在子類建構函式中建立基類執行個體var base = new CollectionBase();需要在建構函式開頭(即任何向base添加屬性和方法之前)。
應用情境:沒有太經典的應用情境,不過對於基類比較複雜,而子類需要添加的屬性方法很少的繼承,執行個體法還是顯得挺清晰的。特別是對於JScript對象動態擴充很熟悉的人,就更覺得明確了。
to be continued ...