随笔 - 81  文章 - 1033  trackbacks - 0
<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

在浮躁的年代里,我们进取心太切,患得患失;虚荣心太强,战战兢兢。一心争强好胜,惟恐榜上无名。
I think I can fly , and flying like a bird !
程序员一名,已售出,缺货中!

我的邮件联系方式

用且仅用于MSN

博客点击率
free web counter
free web counter

常用链接

留言簿(36)

随笔档案

搜索

  •  

积分与排名

  • 积分 - 178611
  • 排名 - 293

最新评论

阅读排行榜

评论排行榜

原文出处:http://www.blogjava.net/ilovezmh/archive/2007/04/16/111106.html


一、继承的方式
1.对象冒充
function ClassA(sColor) {
    this.color = sColor;
    this.sayColor = function () {
        alert(this.color);
    };
}

function ClassB(sColor, sName) {
    this.newMethod = ClassA;
    this.newMethod(sColor);
    delete this.newMethod;
   
    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };   
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();
所有新的属性和新的方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法。
对象冒充可以支持多继承。
function ClassZ(){
   this.newMethod = ClassX;
   this.newMethod(sColor);
   delete this.newMethod;

   this.newMethod = ClassY;
   this.newMethod(sColor);
   delete this.newMethod;
}
这里存在一个弊端,如果ClassX和ClassY具有相同的属性或方法,ClassY具有高优先级,因为继承的是最后的类。

2.call()方法
call()方法是与经典的对象冒充方法最相似的方法,它的第一个参数用作this的对象,其他参数都直接传递函数自身。
function ClassA(sColor) {
    this.color = sColor;
    this.sayColor = function () {
        alert(this.color);
    };
}

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.call(this, sColor);

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

3.apply()方法
apply()方法有两个参数,用作this的对象和要传递参数的数组。例如:
function ClassA(sColor) {
    this.color = sColor;
    this.sayColor = function () {
        alert(this.color);
    };
}

function ClassB(sColor, sName) {
    //this.newMethod = ClassA;
    //this.newMethod(color);
    //delete this.newMethod;
    ClassA.apply(this, arguments);

    this.name = sName;
    this.sayName = function () {
        alert(this.name);
    };
}

var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();

当然,只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象。如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。此外,还可以使用call()方法。

4.原型链
function ClassA() {
}

ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () {
    alert(this.color);
};

function ClassB() {
}

ClassB.prototype = new ClassA();

ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
    alert(this.name);
};

var objA = new ClassA();
var objB = new ClassB();
objA.color = "red";
objB.color = "blue";
objB.name = "Nicholas";
objA.sayColor();
objB.sayColor();
objB.sayName();
注意,调用ClassA的构造函数时,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
原型链的弊端是不支持多重继承。

5.混合方式
与创建对象最好方式相似,用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。
function ClassA(sColor) {
    this.color = sColor;
}

ClassA.prototype.sayColor = function () {
    alert(this.color);
};

function ClassB(sColor, sName) {
    ClassA.call(this, sColor);
    this.name = sName;
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () {
    alert(this.name);
};


var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();
objB.sayColor();
objB.sayName();


二、其他继承方式
1.zlnherit库
可以从http://www.nczonline.net/downloads处下载
zInherit库给Object类添加了两个方法,inheritFrom()和instanceOf()
ClassB.prototype.inheritFrom(ClassA);
CalssB.instanceOf(ClassA);

2.xbObjects库
可以从http://archive.bclary.com/xbprojectsdocs/xbobject/处下载
第一步,必须注册类。
_classes.registerClass("Subclass_Name","Superclass_Name");
         这里,子类和超类名都以字符串形式传进来,而不是指向它们的构造函数的指针。这个调用必须放在指定子类的构造构函数前。
第二步,在构造函数内调用defineClass()方法,传给它类名及被Clary称为原型函数的指针,该函数用于初始化对象的所有属性和方法。

_classes.registerClass("ClassA");
function ClassA(color){
   _classes.defineClass("ClassA",prototypeFunction);

   function prototypeFunction(){
      //...
   }
}
第三步,为该类创建init()方法。该方法负责设置该类的所有属性,它必须接受与构造函数相同的参数。作为一种规约,init()方法总是在defineClass()方法后调用。
_classes.registerClass("ClassA");
function ClassA(color){
   _classes.defineClass("ClassA",prototypeFunction);
   this.init(sColor);
   function prototypeFunction(){
     ClassA.prototype.init = function(sColor){
         this.parentMethod("init");
         this.color = sColor;
      }
   }
}
第四步,在原型函数内添加其他类的方法。
_classes.registerClass("ClassA");
function ClassA(color){
   _classes.defineClass("ClassA",prototypeFunction);
   this.init(sColor);
   function prototypeFunction(){
     ClassA.prototype.init = function(sColor){
         this.parentMethod("init");
         this.color = sColor;
      }
      ClassA.prototype.sayColor = function(){
         alert(this.color);
      }
   }
}
然后,即可以以常规方式创建ClassA的实例
var objA = new ClassA("red");
objA.sayColor();      //outputs "res"
posted on 2007-04-19 15:41 cresposhi 阅读(1115) 评论(1)  编辑  收藏

FeedBack:
# re: javascript学习笔记(二)--继承【转载自好朋友祝子的blog】  2008-03-06 12:01 kirari_wxy
你这里也荒了? 呵呵  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: