打印

javascript中类的创建和继承

类的定义

类定义有三种基本方法,

1、创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co()
2、创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new Co()
3、原型方式,利用对象的prototype属性,例如 function Co(){}; Co.prototype.a = 1; 用这种方式创建对象: var o = new Co()
可灵活运用这三种方式进行组合

类的继承

类的继承有两种基本方法

1、对象冒充 基本原理: 构造函数使用this关键字给所有属性和方法赋值(构造函数实际上仅仅是赋值函数),所以可以利用一种方式,在类内部直接运行赋值函数,把其this关键字传递给新类。例如:
复制内容到剪贴板
代码:
var a = function(){   
    this.a = 1;   
    this.b = 2;   
    alert(this);   
}   
  
var b = function(){   
    this.aa = a;//对a中的this进行转换,同样的方式还有   
    this.aa();   
    delete this.aa;  //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法   
  
    //或者   
    a.call(this,arg1,arg2);   
    //或者   
    a.apply(this,[args]);   
}   
  
var ob = new b();     
var a = function(){
    this.a = 1;
    this.b = 2;
    alert(this);
}
var b = function(){
    this.aa = a;//对a中的this进行转换,同样的方式还有
    this.aa();
    delete this.aa;  //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法
    //或者
    a.call(this,arg1,arg2);
    //或者
    a.apply(this,[args]);
}
var ob = new b();    
2、原型链

基本原理:关于原型链,详见(http://www.javaeye.com/topic/53537)把超类的一个实例付给子类的prototype对象,即可把超类的固定属性和方法传递给子类,要注意一点,这种方法无法在实例化时传递参数,所以一般采用混合方式进行类的继承。

prototype.js中的类定义和继承

1.6.0以前:
复制内容到剪贴板
代码:
/** obsolete syntax **/   
var Person = Class.create();    //通过Class.create方法创建空类   
Person.prototype = {               //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性   
  initialize: function(name) {   
    this.name = name;   
  },   
  say: function(message) {   
    return this.name + ': ' + message;   
  }   
};   
  
var guy = new Person('Miro');   
guy.say('hi');   
// -> "Miro: hi"   
                                            //prototype中的继承方式:   
var Pirate = Class.create();    //建立空类;   
// inherit from Person class:   
Pirate.prototype = Object.extend(new Person(), {    //先实例化超类,再把超类中的方法复制到子类中去,   
  // redefine the speak method                               //注意,实际上prototype类定义机制中并没有直接定义   
say: function(message) {                                       //类的属性而是通过intilize方法,而且所有的方法都   
    return this.name + ': ' + message + ', yarr!';      //之直接定义在prototype中,所以直接用原型链方式   
  }                                                                        //继承超类的所有方法不会产生问题。   
});   
  
var john = new Pirate('Long John');   
john.say('ahoy matey');   
// -> "Long John: ahoy matey, yarr!"  
/** obsolete syntax **/
var Person = Class.create();    //通过Class.create方法创建空类
Person.prototype = {               //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
};
var guy = new Person('Miro');
guy.say('hi');
// -> "Miro: hi"
                                            //prototype中的继承方式:
var Pirate = Class.create();    //建立空类;
// inherit from Person class:
Pirate.prototype = Object.extend(new Person(), {    //先实例化超类,再把超类中的方法复制到子类中去,
  // redefine the speak method                               //注意,实际上prototype类定义机制中并没有直接定义
say: function(message) {                                       //类的属性而是通过intilize方法,而且所有的方法都
    return this.name + ': ' + message + ', yarr!';      //之直接定义在prototype中,所以直接用原型链方式
  }                                                                        //继承超类的所有方法不会产生问题。
});
var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"
来看一下Class.create方法的实现代码
复制内容到剪贴板
代码:
var Class = {   
  create: function() {   
    return function() {                                          //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中,   
      this.initialize.apply(this, arguments);              //然后通过对象冒充方式继承该类   
    }   
  }   
}            
var Class = {
  create: function() {
    return function() {                                          //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中,
      this.initialize.apply(this, arguments);              //然后通过对象冒充方式继承该类
    }
  }
}    
可以从prototype的例子充分体会到通过对象冒充和原型链类继承的差别,一般来说属性需用对象冒充方式继承,方法需用原型链方式继承。

prototype-1.6.0以后版本:

Java代码
1.6.0以后,对prototype的类进行了更多的扩展,举例:
复制内容到剪贴板
代码:
/** new, preferred syntax **/   
// properties are directly passed to `create` method   
var Person = Class.create({   
  initialize: function(name) {                       //不必定义一个空类,and定义方法的位置改变   
    this.name = name;   
  },   
  say: function(message) {   
    return this.name + ': ' + message;   
  }   
});   
  
// when subclassing, specify the class you want to inherit from   
var Pirate = Class.create(Person, {            //第一个参数是class,作为超类在定义类时直接继承   
  // redefine the speak method   
say: function($super, message) {   
    return $super(message) + ', yarr!';   
  }   
});   
  
var john = new Pirate('Long John');   
john.say('ahoy matey');   
// -> "Long John: ahoy matey, yarr!"   
1.6.0以后,对prototype的类进行了更多的扩展,举例:
复制内容到剪贴板
代码:
/** new, preferred syntax **/
// properties are directly passed to `create` method
var Person = Class.create({
  initialize: function(name) {                       //不必定义一个空类,and定义方法的位置改变
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
});
// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {            //第一个参数是class,作为超类在定义类时直接继承
  // redefine the speak method
say: function($super, message) {
    return $super(message) + ', yarr!';
  }
});
var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"
实现的代码比较复杂,但是基本原理和1.60以前版本差不多,也是用对象冒充继承initialize类,用原型链继承超类的方法,不过中间定义了一个klass对象,类似于工厂函数的方式
  


声明子类时对子类的initialize进行重写
1.60以前
复制内容到剪贴板
代码:
var Animal = Class.create();   
Animal.prototype = {   
  initialize: function(name, sound) {                                 //超类,顶一个两个参数   
    this.name = name;   
    this.sound = sound;   
  },                 
  
speak: function() {   
alert(name + " says: " + sound + "!");   
}   
};   
  
var snake = new Animal("Ringneck", "hissssssssss");   
snake.speak();   
// -> alerts "Ringneck says: hissssssssss!"   
  
var Dog = Class.create();   
  
Dog.prototype = Object.extend(new Animal(), {   
initialize: function(name) { //子类,定义一个参数   
this.name = name;   
this.sound = "woof";   
}   
});   
  
var fido = new Dog("Fido");   
fido.speak();   
// -> alerts "Fido says: woof!"   
var Animal = Class.create();
Animal.prototype = {
  initialize: function(name, sound) {                                 //超类,顶一个两个参数
    this.name = name;
    this.sound = sound;
  },              
speak: function() {
alert(name + " says: " + sound + "!");
}
};
var snake = new Animal("Ringneck", "hissssssssss");
snake.speak();
// -> alerts "Ringneck says: hissssssssss!"
var Dog = Class.create();
Dog.prototype = Object.extend(new Animal(), {
initialize: function(name) { //子类,定义一个参数
this.name = name;
this.sound = "woof";
}
});
var fido = new Dog("Fido");
fido.speak();
// -> alerts "Fido says: woof!"
1.60以后
复制内容到剪贴板
代码:
var Animal = Class.create({   
  initialize: function(name, sound) {   
    this.name = name;   
    this.sound = sound;   
  },   
            
  
speak: function() {   
alert(this.name + " says: " + this.sound + "!");   
}   
});   
// subclassing Animal   
var Snake = Class.create(Animal, {   
initialize: function($super, name) { //通过$super的方式调用超类的initliaze,   
$super(name, 'hissssssssss');   
}   
});   
var ringneck = new Snake("Ringneck");   
ringneck.speak();   
//-> alerts "Ringneck says: hissssssssss!"   
  
var rattlesnake = new Snake("Rattler");   
rattlesnake.speak();   
//-> alerts "Rattler says: hissssssssss!"   
  
// mixing-in Enumerable   
var AnimalPen = Class.create(Enumerable, {   
initialize: function() {   
var args = $A(arguments);   
if (!args.all( function(arg) { return arg instanceof Animal }))   
throw "Only animals in here!"  
this.animals = args;   
},   
  
// implement _each to use Enumerable methods   
_each: function(iterator) {   
return this.animals._each(iterator);   
}   
});   
var snakePen = new AnimalPen(ringneck, rattlesnake);   
snakePen.invoke('speak');   
//-> alerts "Ringneck says: hissssssssss!"   
//-> alerts "Rattler says: hissssssssss!"   
           
var Animal = Class.create({
  initialize: function(name, sound) {
    this.name = name;
    this.sound = sound;
  },
          
speak: function() {
alert(this.name + " says: " + this.sound + "!");
}
});
// subclassing Animal
var Snake = Class.create(Animal, {
initialize: function($super, name) { //通过$super的方式调用超类的initliaze,
$super(name, 'hissssssssss');
}
});
var ringneck = new Snake("Ringneck");
ringneck.speak();
//-> alerts "Ringneck says: hissssssssss!"
var rattlesnake = new Snake("Rattler");
rattlesnake.speak();
//-> alerts "Rattler says: hissssssssss!"
// mixing-in Enumerable
var AnimalPen = Class.create(Enumerable, {
initialize: function() {
var args = $A(arguments);
if (!args.all( function(arg) { return arg instanceof Animal }))
throw "Only animals in here!"
this.animals = args;
},
// implement _each to use Enumerable methods
_each: function(iterator) {
return this.animals._each(iterator);
}
});
var snakePen = new AnimalPen(ringneck, rattlesnake);
snakePen.invoke('speak');
//-> alerts "Ringneck says: hissssssssss!"
//-> alerts "Rattler says: hissssssssss!"
这样的看了很多了,可不可以讲讲具体的应用?
做个热心人,希望大家都是热心人。
JS 里没有 继承
所有的都只能是伪的
http://www.qlili.com 个人站帮点啊