今天说说脚本面向对象编程中的'实例继承法',这个方法是经典论坛中,介绍JScript面向对象编程的文章中使用的继承方法。它是怎么工作的呢?
实例继承法的原理:
实例继承法的关键代码是其构造函数function ArrayList03()中的:
var base = new CollectionBase();
// ...
return base;
// ...
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();
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
[class ArrayList03]: 2: a,b
[class ArrayList03]: 3: a,b,c
小结:实例继承法其实有些偷梁换柱的味道,因为这样得到的实例,针对instanceOf来说的话,完全是其基类的一个扩展。而子类的实例是被扔掉了的,因为new ArrayList03()返回的是基类实例(return base;)。这完全没有了任何继承的味道,叫做类扩展还贴切些。优点是对基类的编写没有任何特殊要求,不过同样需要规定子类的写法,子类不能使用prototype来导入原型方法,并且在子类构造函数中创建基类实例var base = new CollectionBase();需要在构造函数开头(即任何向base添加属性和方法之前)。
应用场景:没有太经典的应用场景,不过对于基类比较复杂,而子类需要添加的属性方法很少的继承,实例法还是显得挺清晰的。特别是对于JScript对象动态扩展很熟悉的人,就更觉得明确了。
本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。