js的抽象方法

一.JavaScript中类的封装
Javascript不是一种面向对向的语言, 没有提供对类的支持, 因此我们不能像在传统的语言里那样用class来定义类, 但我们可以利用js的闭包封装机制来实现js类, 下面我们以封装一个简单的Shape类来作一个说明.
定义 ShapeBase“类”
1.法则一[this式]
function ShapeBase(){
this.show = function(){
alert(“ShapeBase show”);
};
this.init = function(){
alert(“ShapeBase init”);
};
}
注:这里用到了this来声明,而不是var,后者是用来定义私有方法的。

   2.法则二[prototype式]
   ShapeBase.prototype.show=function(){ 
          alert("ShapeBase show"); 
   } 
   ShapeBase.prototype.init=function(){ 
          alert("ShapeBase init"); 
   }
    或者
    ShapeBase.prototype={
              show:function(){
                      alert("ShapeBase show");
               }
              init:function(){
                       alert("ShapeBase init");
               }       
    }

    同构造java一样,我们写一个主函数调用测试下。如下
     funciton test(){
            var s = new ShapeBase();
            s.init();
            s.show();
     }

    可以看到我们在构造JS类上有两中方式,在调用中我们发现其方式与java类几乎一样,new一个类对象,通过引用发送消息的形式调用具体类的方法。差别仅在于这个时候生成的类对象的类型这里还是记为var。

二.JS抽象类和继承
类的封装我们已经实现了,而面向对象其他的一些优良特性我们也可以通过JS本身的特性来实现。这种化归思想本身就是一种技巧。
我们可以利用JavaScript语言本身的性质来实现其抽象类,也可以通过将父类prototype中的成员方法复制到子类的prototype中来实现其继承机制。
即将面向对象编程中的继承概念转化为javascript语言中的函数属性复制。
1.JS中的实例prototype方法
可实例化的prototype方法
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
2.JS中的虚方法
在传统语言中虚方法要先定义, 而包含虚方法的类就是抽象类,抽象类不能被实例化,但在JavaScript中,虚方法是被看作该类中未定义的方法,但已经通过this指针使用了. 所以JS中的虚方法不需经过声明而直接使用, 并且类也可以被实例化.
静态方法:
Object.extend = function(destination, source){
for(property in source){
destination[property] = source[property];
}
return destination;
}
3.1继承[实例方法prototype]
以object为例。先定义object的extend方法, 一个为静态方法,一个为实例方法, 这两个方法用于通过prototype来实现的继承机制。
实现继承类Rect
function Rect(){
//
}
// 实现继承
Rect.prototype = ShapeBase.prototype;
//扩充新方法
Rect.prototype.add = function(){
alert(“Rect add”);
}
注:这里的继承有一种区别于一般面向对象的继承特性。可能是由于prototype赋值只是简单的改变指向地址,会导致一种现象,即如果重写了“子类”的方法,则“父类”的方法也随之改变。这种权利转移的确让人惊讶。
测试例子如下:
如果在子类重写show方法
Rect.prototype.show = function(){
alert(“Rect show”);
}

   则执行结果如下:
   function test(){
         var s = new ShapeBase();
         //结果显示:Rect show
         s.show(); 

          //结果显示:Rect show
         var r = new Rect();
         //结果显示:Rect add
          r.add();
   }

   3.2继承[静态方法]
   使用object.extend实现继承, 并实现一个oninit虚方法, 修改“父类”ShapeBase如下:
          ShapeBase.prototype = {
                    show:function(){
                               alert("ShapeBase show");
                     }
                     initialize:function(){
                                this.oninit();
                     }
            }
            子类Rect
             Rect.prototype = (new ShapeBase).extend({
                         //添加新方法
                         add:function(){
                                  alert("Rect add");
                          },
                         // 重写show方法而不改变父类方法
                         show:function(){
                                  alert("Rect show");
                         },
                         //实现虚方法
                         oninit:function(){
                                 alert("Rect oninit");
                          }
             })

             测试类如下:
             function test(src){
                     var s = ShapeBase();
                     //显示ShapeBase show[来自父类]
                     s.show();
                     var r = new Rect();
                     //显示Rect show [来自子类]
                     r.show();
                     //显示Rect add [来自子类扩充方法]
                     r.add();
                      //显示Rect oninit [来自实现的oninit方法]
                     r.initialize();
             }

三.特定对象创建类
特定对象实现属性复制
function extend(des, src){
if(!des){
des = {};
}
if(src){
for(var i in src){
des[i] = src [i];
}
}

        return des;

   }

   //全局变量
   var CC = {};
   //设置create用于创建类
   CC.create = function(superclass,constructor){
           var clazz = (function(){
                  this.initialize.apply(this,arguments);
           });
                   //如果无参数,则直接返回类
                   if(arguments.length == 0){
                             return clazz;
                   }
                   //如果父类此时constructor应该成为一个纯对象,直接复制属性返回
                   if(!superclass){
                             extend(clazz.prototype,constructor);
                             return clazz;
                   } 

                   var absObj = clazz.prototype,
                         sprPropty = superclass.prototype;
                   if(sprProty){
                         //用于访问父类方法
                         clazz.superclass  = prototype;
                         extend(absObj ,sprPropty);
                         //调用属性构造函数创建属性。实现的关键
                         extend(absObj, constructor(sprPropty));
                     //子类实例直接通过obj.superclass访问父类属性。
                    //如果不想造成过多引用,可以把这句注释掉。多数时候也没有必要
                         absObj.superclass = sprPropty;
                         clazz.constructor = constructor;
                    }
                    return clazz;
   }

   //创建一个动物类
   var Animal = CC.create(null ,{
             //属性
             footprint:‘-------------------=’,
             //类初始化方法。当用new生成一个类时该方法自动被调用。参见上述                  //定义
             initialize:function(options){
                     extend(this,options);
                     alert("Animal initialize method is called.");
             }
             eat:function(){
                      alert("Animal eat method is called");
             }
             move:function(){
                      alert("I am moving like this '+ this.footprint+' .");
             }
      });

      //创建一个Duke类
      var Duke = CC.create(Animal,function(superclass){
               //此处可定义类全局静态数据,该类每个实例都共享这些数据。
               //计算实例个数,包括派生类实例
               var static_instance_counter = 0;
               function classUtilityFuncHere(){};
               //返回类具体属性
               return{
                      // 重写初始化方法
                      initialize:function(){
                             alert("initializing Duke class");
                      }
                      //调用父类初始化。比一般其它库要简洁。
                      superclass.initialize.call(this,options);
                      //子类扩充
                      alert("Duke initialize method is called.");
                      //读取或修改类静态属性
                      static_instance_couter++;

               },

               //重写move方法并增加Duke自己的移动方式
               move:function(){
                      this.footprint = this.footprint + "zzzzzzzzzzzzz";
                      superclass.move.call(this);
               },
               //重写eat方法,覆盖父类eat方法
               eat:function(){
                      alert("Duke is eating");
               },
               //子类新增自己的方法,显示当前已经初始化的Duke类实例数量
               say:function(){
                     alert("The number of Duke instance is ' + static_instance_counter' ");
               }
      };

      });

      var DukeChild = CC.create(Duke,function(superclass){
               return{
                       move:function(){
                              this.footprint = this.footprint + "++++++=";
                              superclass.move.call(this);
                       },
                       say:function(){
                              alert("this.msg ||");
                       }
               };

       })

       测试类:
       function test(){
             var animal = new Animal();
             animal.eat()
             animal.move();
             var dukeA = new Duke();
             dukeA.eat();
             dukeA.move();
             dukeA.say();
             var dukeB = new Duke();
             dukeB.eat();
             dukeB.move();
             dukeB.say();
             var dukeC = new DukeChild({msg:'I am a child of duke'});
             duckC.move();
             duckC.say();
       }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值