已有的一个功能模块a,我想继承a并扩展a中的部分方法,搞半天没弄出来,大家来看看怎么解决。var Class = function(properties) {
var _class = function() {
return (arguments[0] !== null && this.initialize && typeof (this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
};
_class.prototype = properties;
return _class;
};
//模块a简化代码
var a = new Class({
initialize : function(options) {
alert("a");
},
show : function() {
alert("a-show");
}
});
var d = new Class(a.prototype);
d.prototype.show=function(){
//这里如何调用a的show?
alert("d-show");
}请问如何写这个d并扩展a的show方法?
-------------------------------------------------
顺便BS下
老大:怎么这么早下班回家啊?
5.30下班时间我6点多走这也早,汗。虽然还未转正也不至于这样吧,没任务留我干嘛,大冬天的?

解决方案 »

  1.   

    这结构就算是继承,不要去用 var d = new Class(a.prototype); 这种方式。设计不对。推荐方案,设计时,先制定使用规则。再去实现规则var A = Class('A', { show : function(){}, open:function(){}}); // 创建一个类A
    var B = Class('B', A, {show : function(){}}); //创建类B,并继承Avar a = new A();
    var b = new B();// 满足基本鉴别
    a instanceof A      // true
    b instanceof B      // true
    b instanceof A      // true
    a instanceof Object // true
    b instanceof Object // true// 满足基本覆盖
    a.show(); // show a的内容
    b.show(); // show b的内容
    b.open(); // 执行A中的open()// 满足多态,涉及到this和super
    // 满足封装,可随心所欲私有化任何属性或方法
    .
    .
    .再来实现规则,实现Class,让Class返回的东西,可以满足以上所有条件
    Class = function(){
         //   把你的实现代码写在这
    }
      

  2.   

    var $Class = function(className, superClass, classBody){
       switch(arguments.length){
           case 2:
            classBody = superClass;
            superClass = null;
            break;
           case 3: break;
           default: throw '参数列表错误';
       }
       
       // 新的类
       var cls = function(){};
       cls.className = className;
       
       // 继承
       if (superClass) {
       var f = function(){};
       f.prototype = superClass.prototype;
       cls.prototype = new f();
       
       // 每个子类,可得到自己父类类型
       cls.superClass = superClass;
       }
       
       // 提供一个默认的构造方法,且构造方法名称与类名相同
       var fName = className.split('.');
       fName = fName[fName.length - 1]; // 数组有个直接取最后一个元素,方法名不记得了。自己查查看吧
       cls.prototype[className] = function(){};
       
       // 覆盖,自定义构造方法会覆盖默认构造方法
       for (var n in classBody) {
       n && (cls.prototype[n] = classBody[n]);
       }
       
       // 特殊方法, 所有对象都有个获取自身类型的方法
       cls.prototype.getClass = function(){
       return cls;
       };
         cls.prototype.constructor = cls;   return cls;
    };var A = $Class('A', {show:function(){alert('a');}});
    var B = $Class('B', A, {show:function(){alert('b');}});var a = new A();
    var b = new B();// 满足基本鉴别
    //a instanceof A // true
    //b instanceof B // true
    //b instanceof A // true
    //a instanceof Object // true
    //b instanceof Object // truea.show(); // a
    b.show(); // b只是简单测试了一下。你参考一下
      

  3.   

    写的很详细,先说声感谢。
    不过没有举例如何把b的show方法扩展a的show方法,只是覆盖了而已。
    我的本意其实就是不用重复copy同样的一堆代码里来实现原有功能扩展(保留原功能)。
      

  4.   

    这个就涉及到super的概念只需要在b的show中主动调用父类a的showvar B = $Class('B', A, {
        B : function(){
            // 子类构造方法,需要自动调用。但我给的例子还没写这一步。你自己去实现吧
        },    // 扩展父类方法 = 覆盖 + 再去主动调用父类方法
        show : function(){
            alert('b');        // 取访问父类方法, 这句代码比较长,意思是取得父类类型,并以子类对象去调用父类方法
            this.getClass().superClass.prototype.show.call(this, '必要时,还可以传参数给父类方法');
        }
    });new B().show(); // 先 b,后a
      

  5.   

    恩 试过这个是可以,但是没法在new b的时候调用b的带参默认构造方法了,你可以看我的例子a的创建方法。
    假设用你的方法创建了b继承a后,那直接调用b.initialize();初始化都不行了。
      

  6.   

    说错了,是只能b.initialize();来初始化了
      

  7.   

    。。我给你的例子没有去实现在new B()的时候自动调用B的构造方法。你可以自己实现。代码都是临时敲的。肯定不可能给你把整个oop模式敲完。这样吧,给你个地址,你去访问。是我写的纯OOP模式的js。地址要晚上发上来,现在在公司。我回家开服务器吧,是oop写的一个webos - -!给你看一段代码://  [创建接口]
          Fan.interface('Fan.test.IA', function(){
              this.INFO = 'Fan.test.IA';
              this.showA = Function;
          });
          
          Fan.interface('Fan.test.IB', function(){
              this.INFO = 'Fan.test.IB';
              this.showB = Function;
          });
       
      //  [接口继承]  
          Fan.interface('Fan.test.IC', Fan.test.IB, Fan.test.IA, function(){
              this.INFO = 'Fan.test.IC';
              this.showC = Function;
          });
       
      //  [创建类] 默认继承Object
          Fan.clazz('Fan.test.DImpl', function(){
              var _d;
              this.DImpl = function(d){
               $super();
               _d = d;
              };
              
              this.showA = function(){
                  return _d;
              };
          });
          
      //  [类继承]
          Fan.clazz('Fan.test.EImpl', Fan.test.DImpl, function(){
           //alert('2:' + cfg);
            this.a = null;
              this.b = null;
              this.c = null;
              
              this.EImpl = function(cfg){
               $super(cfg.d); // 带参数调用父类构造方法
               this.a = 'EImpl.a';
                  this.b = cfg.b;
                  this.c = cfg.c;
              };
       
              this.showA = function(){
                  return this.a;
              };
         });
       
      //  [类继承+实现接口]
          Fan.clazz('Fan.test.FImpl', Fan.test.EImpl, Fan.test.IC, Fan.test.IB, function(){
           //alert('1:' + cfg);
              this.a = 'FImpl.a';
              
            this.FImpl = function(cfg){
             $super(cfg);
             };
       
              this.showA = function(){
                  return this.a;
              };
              this.showB = function(){
                return this.b;
              };
              this.showC = function(){
                  return this.c;
              };
              this.showF = function(){
                  return 'Fan.test.FImpl';
              };
          });
       
      //  [使用]
          f = new Fan.test.FImpl({a:'aa', b:'bb', c:'cc', d:'dd'});
          logger.info('f.showA() == ' + f.showA());
          if(f.showA() == 'FImpl.a'){
           logger.info('子类调用正常');
          } else {
           logger.error('子类调用异常');
          }
      

  8.   

    服务器已开启
    http://diky87688973.gicp.net:8080