zoukankan      html  css  js  c++  java
  • JS 抽象类

    6.7  实现抽象类

    6.7.1  抽象类和虚函数
    虚函数是类成员中的概念,是只做了一个声明而未实现的方法,具有虚函数的类就称之为抽象类,这些虚函数在派生类中才被实现。抽象类是不能实例化的,因为其中的虚函数并不是一个完整的函数,不能被调用。所以抽象类一般只作为基类被派生以后再使用。
    和类的继承一样,JavaScript并没有任何机制用于支持抽象类。但利用JavaScript语言本身的性质,可以实现自己的抽象类。

    6.7.2  在JavaScript实现抽象类
    在传统面向对象语言中,抽象类中的虚方法必须先被声明,但可以在其他方法中被调用。而在JavaScript中,虚方法 就可以看作该类中没有定义的方法,但已经通过this指针使用了。和传统面向对象不同的是,这里虚方法不需经过声明,而直接使用了。这些方法将在派生类中 实现,例如:
    <script language="JavaScript" type="text/javascript">
    <!--
    //定义extend方法
    Object.extend = function(destination, source) {
      for (property in source) {
        destination[property] = source[property];
      }
      return destination;
    }
    Object.prototype.extend = function(object) {
      return Object.extend.apply(this, [this, object]);
    }
    //定义一个抽象基类base,无构造函数
    function base(){}
    base.prototype={
          initialize:function(){
                   this.oninit(); //调用了一个虚方法
          }
    }
    //定义class1
    function class1(){
          //构造函数
    }
    //让class1继承于base并实现其中的oninit方法
    class1.prototype=(new base()).extend({
          oninit:function(){ //实现抽象基类中的oninit虚方法
                 //oninit函数的实现
          }
    });
    //-->
    </script>
    这样,当在class1的实例中调用继承得到的initialize方法时,就会自动执行派生类中的oninit()方法。从这里也可以看到解释型语言执 行的特点,它们只有在运行到某一个方法调用时,才会检查该方法是否存在,而不会向编译型语言一样在编译阶段就检查方法存在与否。JavaScript中则 避免了这个问题。当然,如果希望在基类中添加虚方法的一个定义,也是可以的,只要在派生类中覆盖此方法即可。例如:
    //定义一个抽象基类base,无构造函数
    function base(){}
    base.prototype={
         initialize:function(){
              this.oninit(); //调用了一个虚方法
         },
         oninit:function(){} //虚方法是一个空方法,由派生类实现
    }

    6.7.3  使用抽象类的示例
    仍然以prototype-1.3.1为例,其中定义了一个类的创建模型:
    //Class是一个全局对象,有一个方法create,用于返回一个类
    var Class = {
       create: function() {
         return function() {
           this.initialize.apply(this, arguments);
         }
       }
    }
    这里Class是一个全局对象,具有一个方法create,用于返回一个函数(类),从而声明一个类,可以用如下语法:
    var class1=Class.create();
    这样和函数的定义方式区分开来,使JavaScript语言能够更具备面向对象语言的特点。现在来看这个返回的函数(类):
    function(){
          this.initialize.apply(this, arguments);
    }
    这个函数也是一个类的构造函数,当new这个类时便会得到执行。它调用了一个initialize方法,从名字来看,是类的构造函数。而从类的角度来看, 它是一个虚方法,是未定义的。但这个虚方法的实现并不是在派生类中实现的,而是创建完一个类后,在prototype中定义的,例如prototype可 以这样写:
    var class1=Class.create();
    class1.prototype={
          initialize:function(userName){
                          alert(“hello,”+userName);
          }
    }
    这样,每次创建类的实例时,initialize方法都会得到执行,从而实现了将类的构造函数和类成员一起定义的功能。其中,为了能够给构造函数传递参数,使用了这样的语句:
    function(){
          this.initialize.apply(this, arguments);
    }
    实际上,这里的arguments是function()中所传进来的参数,也就是new class1(args)中传递进来的args,现在要把args传递给initialize,巧妙的使用了函数的apply方法,注意不能写成:
    this.initialize(arguments);
    这是将arguments数组作为一个参数传递给initialize方法,而apply方法则可以把arguments数组对象的元素作为一组参数传递过去,这是一种很巧妙的实现。
    尽管这个例子在prototype-1.3.1中不是一个抽象类的概念,而是类的一种设计模式。但实际上可以把Class.create()返回的类看作 所有类的共同基类,它在构造函数中调用了一个虚方法initialize,所有继承于它的类都必须实现这个方法,完成构造函数的功能。它们得以实现的本质 就是对prototype的操作。

    转载:未找到真正出处。

  • 相关阅读:
    c# 三元运算符 表达式赋值的时候 我老容易写错 备注下
    wpf 图片操作类 ImageBrush BitmapImage
    WPF 结合 微软的手写板 进行输入
    c# 经纬度距离计算
    c# 通用类扩展方法 备注
    Android SDK Manager无法更新的解决(转帖)
    GridControl相关设置
    SDK Manager.exe运行一闪而过
    “LC.exe”已退出 或者 设计器提示控件为声明
    建立管理员帐户
  • 原文地址:https://www.cnblogs.com/yuzhongwusan/p/2513386.html
Copyright © 2011-2022 走看看