• JavaScript ----------- 组合继承


    继承

    实现继承:继承实际的方法。ECMAScript 只支持实现继承,而且其实现基础主要是依靠原型链来实现的。

      基本思想是:利用原型来实现一个引用类型继承另外一个引用类型的属性和方法。

            原型 - 构造函数 - 实例 之间的关系

            构造函数(prototype) <-------> 原型(constructor) <------- 实例(_proto_)

    实现原型链有一种基本模式,其代码大致如下

     1 function SuperType(){
     2 
     3 this.property = true;
     4 }
     5 
     6 SuperType.prototype.getSuperValue = function(){
     7     return this.prototype;
     8 }
     9 function SubType(){
    10     this.subproperty = false;
    11 }
    12 
    13 //继承了SuperType
    14 
    15 SubType.prototype = new SuperType();
    16 
    17 SubType.prototype.getSubValue = function(){
    18     return this.subproperty;
    19 } 
    20 
    21 var instance = new SubType();
    22 alert(instance.getSuperValue());
    23 
    24 
    25 function SuperType(){
    26     this.property = true;
    27 }
    28 
    29 SuperType.prototype.getSuperValue = function(){
    30     return this.property;
    31 }
    32 
    33 function SubType(){
    34     this.subproperty = false;
    35 }
    36 SubType.prototype = new SuperType();
    37 
    38 SubType.property = {
    39     getSubValue:function(){
    40         return this.subproperty;
    41     },
    42     someOtherMethod:function(){
    43         return false;
    44     }
    45 }
    46 
    47 var instance = new SubType();
    48 alert(instance.getSuperValue());        


    6.3.1 既在通过原型进行继承时,不能使用字面量的方法创建原型内容,因为这样会重写原型链

    原型中存在的最大问题是:


      1 引用类型值得共用问题

      2 用原型实现的继承,由于属性共用,在创建子类型实例时,不能向超类型的构造函数中传递参数。

    6.3.2 借用构造函数

      call() apply()


    在解决原型中包含引用类型值所带来问题的过程中,可以使用一种叫借用构造函数的技术(有时候也叫做伪造对象或经典继承)。这种技术的基本思想相当简单,既在子类型构造函数的内部调用超类型构造函数。别忘了,函数
    只不过是在特定环境中执行代码的对象,因此通过使用apply()和 call()方法也可以在新创建的对象上执行构造函数,

    function SuperType(){
        this.colors = ["red","blue","green"];
    }
    
    function SubType(){
        SuperType.call(this);
    }
    
    var instance = new SubType();
    instance.colors.push("black");
    
    alert(instance.colors); //red blue green black
    
    var instance1 = new SubType();
    
    
    alert(instance1.colors); // red blue green

    借用构造函数相比原型模式的优点:

    · 传递参数

    例如:

    function SuperType(name){
        this.name = name;
    }
    
    function SubType(){
        SuperType.call(this,"Nicholas");
        this.age = 20;
    }
    
    var instance = new SubType();
    alert(instance.name); // Nicholas
    alert(instance.age); //20 



    借用构造函数的问题
    如果仅仅是借用构造函数,那么也将无法避免构造函数模式存在的问题------ 方法都在构造函数中定义,因此函数复用就无从谈起了。

    6.3.3  

    组合继承(combination inheritance) 原型与借用构造函数两种方法取其长的一种组合方式

    主要思想:
      利用原型对属性和方法的继承 而通过借用构造函数来实现对实例属性的继承。

    这样既然继承原型中属性,又能保证实例拥有自己的属性。

        
           function SuperType(name){
                this.name = name;
                this.colors = ["red","blue","green"];
            }
            
            SuperType.prototype.sayName = function(){
                alert(this.name);
            }
            
            function SubType(name,age){
                //继承
                SuperType.call(this,name);
                this.age = age;
            }
            
            //继承方法
            
            SubType.prototype = new SuperType();
            SubType.prototype.constructor = SubType;
            SubType.prototype.sayAge = function(){
                alert(this.age);
            }
            
            var instance1 = new SubType("Nicholas",20);
            instance1.colors.push("black");
            alert(instance1.colors);
            instance1.sayName();
            instance1.sayAge();
            
            var instance2 = new SubType("Greg",27);
            alert(instance2.colors);
            instance2.sayName();
            instance2.sayAge
            
      


      在这个例子中,SuperType 构造函数定义了两个属性: name 和 colors. SuperType的原型定义了一个方法sayName(). SubType()构造函数在调用 SuperType 构造函数时传入了name参数,紧接着又定义了它自己的属性age。

    然后,将SuperType的实例赋值给SubType的原型,然后又在新原型上定义了方法sayAge(). 这样一来,就可以让两个不同的SubType实例既分别拥有自己的属性----包括colors 属性,又可以使用相同的方法了。

      组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点。 而且 instanceof 和 isPrototypeOf 也能够用于识别基于组合继承创建的对象。

  • 相关阅读:
    hdu1069Monkey and Banana(动态规划)
    hdu2571 命运(动态规划)
    hdu1505City Game(动态规划)
    在jvm底层有关于方法区的介绍
    用IDEA查看源码总是跳到.class文件而不是.java文件的解决办法
    如果Son类继承Father类,Father类继承GrandFather类,那么new Son()创建对象的时候是否会执行GrandFather类里面的方法
    看面试题有感:子类构造器(无参或有参)继承的super()方法在何时调用,与静态代码块,普通代码块相比的执行顺序如何的思考及证明
    关于子类构造器调用super()方法的规定
    为什么重写了equals方法后还需要重写hashCode方法
    字符串常量池处在JVM的堆中,那么是在堆的哪个部分呢
  • 原文地址:https://www.cnblogs.com/czhyuwj/p/5616219.html
Copyright © 2020-2023  润新知