javascript学习笔记(七)---继承的实现
ECMAScript中实现继承的方式不止一种。这是因为JavaScript中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非由解释程序处理。
?
对象冒充---构造函数使用function ClassA(sColor){this.color = sColor;this.sayColor = function (){alert(this.color);}}function ClassB(sColor,sName){this.newMethod = ClassA;//为ClassA赋予了方法newMethodthis.newMethod(sColor);//调用newMethoddelete this.newMethod;//删除对ClassA的引用this.name = sName;this.sayName = function(){alert(this.name);}}
?
?所有的新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法.
?可以实现多继承
?
function ClassA(sColor){this.color = sColor;this.sayColor = function (){alert(this.color);}}function ClassB(sColor,sName){ClassA.call(this,sColor); //this让ClassA中的关键字this等于新创建的ClassB对象//第二个参数sColor对两个类来说都是唯一的参数。this.name = sName;this.sayName = function(){alert(this.name);}}?
function ClassA(sColor){this.color = sColor;this.sayColor = function (){alert(this.color);}}function ClassB(sColor,sName){ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。this.name = sName;this.sayName = function(){alert(this.name);}}
?
原型链---用另一类型的对象重写类的function ClassA(){}ClassA.prototype.name = "nomad";ClassA.prototype.sayName = function(){alert(this.name);}function ClassB()}ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。ClassB.prototype.age = 23;ClassB.prototype.sayAge = function(){alert(this.age);}?
混合方式---对象冒充继承构造函数的属性,用原型链继承function ClassA(aName){this.name = aName;}ClassA.prototype.sayName = function(){alert(this.name);}function ClassB(aName,aAge){ClassA.call(this,aName);}ClassB.prototype = new ClassA();ClassB.prototype.sayAge = function(){alert(this.age);}?
其他继承方式:
zInherit库(<script type="text/javascript" src="~/zinherit.js"></script>function ClassA(){}ClassA.prototype.name = "nomad";ClassA.prototype.sayName = function(){alert(this.name);}function ClassB(){}ClassB.prototype.inheritFrom(ClassA); ClassB.prototype.age = 23;ClassB.prototype.sayAge = function(){alert(this.age);}
?
?
xbObjects:为JavaScript提供更强的面向对象范型,不止支持继承,还支持方法的重载和调用超类方法的能力。
?(xbObjects.js见附件)
?
几个方法:
--registerClass(className, parentClassName):参数以字符串形式传递,如父类不明确,可以只用第一个参数
--defineClass(className, prototype_func):className为字符串形式的类名,prototype_func为函数指针(函数名)
--parentMethod(method,args...):接受任意多个参数,但第一个参数总是要调用的父类方法的名字(该参数必须是字符串,而不是函数指针),所有其他参数都被传给父类的方法。
---
//1,必须注册类_classes.registerClass("Polygon");function Polygon(iSides) { //2,在构造函数内调用defineClass()方法 _classes.defineClass("Polygon", prototypeFunction); //3, this.init(iSides); //该函数用于初始化对象的所有属性和方法 function prototypeFunction() { Polygon.prototype.init = function(iSides) { this.parentMethod("init"); this.sides = iSides; }; Polygon.prototype.getArea = function () { return 0; }; }}_classes.registerClass("Triangle", "Polygon");function Triangle(iBase, iHeight) { _classes.defineClass("Triangle", prototypeFunction); this.init(iBase,iHeight); function prototypeFunction() { Triangle.prototype.init = function(iBase, iHeight) { this.parentMethod("init", 3); this.base = iBase; this.height = iHeight; }; Triangle.prototype.getArea = function () { return 0.5 * this.base * this.height; }; } }_classes.registerClass("Rectangle", "Polygon");function Rectangle(iLength, iWidth) { _classes.defineClass("Rectangle", prototypeFunction); this.init(iLength, iWidth); function prototypeFunction() { Rectangle.prototype.init = function(iLength, iWidth) { this.parentMethod("init", 4); this.length = iLength; this.width = iWidth; } Rectangle.prototype.getArea = function () { return this.length * this.width; }; }}??
1 楼 prcjack 2008-06-22 引用:原型链--- 缺点:使用原型链,就无法使用带参构造函数了