zoukankan      html  css  js  c++  java
  • 继承

    许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,实现继承则继承实际的方法。由于函数没有签名,在ECMAScript中无法实现接口继承。ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的。实现的本质是重写原型对象,代之以一个新类型的实例。

    1.原型链

        function SuperType(){
            this.property=true;
        }
    
        SuperType.prototype.getSuperValue=function(){
            return this.property;
        };
    
        function SubType(){
            this.subProperty=false;
        }
    
        //继承了SuperType
        SubType.prototype = new SuperType();
    
        SubType.prototype.getSubValue=function(){
            return this.subProperty;
        };
    
        var instance = new SubType();
        alert(instance.getSuperValue());  //true

    我们没有使用SubType默认提供的原型,而是给它换了一个新原型,这个新原型就是SuperType的实例。于是,新原型不仅具有作为一个SuperType的实例所拥有的全部属性和方法,而且其内部还有一个指针,指向了SupperType的原型。最终:instance指向SubType的原型,SubType的原型又指向SuperType的原型。getSuperValue方法仍然存在于SuperType.prototype中,但property则位于SubType.prototype中。这是因为property是一个实例属性,而getSuperValue则是一个原型方法。

    另外,在通过原型链实现继承时,不能使用对象字面量创建原型方法,因为这样做就会重写原型链。(因为直接赋在了prototype上,而不是赋在了添加到prototype的某个方法上)。

    问题:就像创建对象时遇到的问题一样,包含引用类型值的原型属性会被所有实例所共享,而这也正是为什么要在构造函数中,而不是在原型对象中定义属性的原因。现在,在通过原型来实现继承时,原型实际上会变成另一个类型的实例,于是,原先的实例属性也就变成了现在的原型属性了。

        function SuperType(){
            this.colors=["red","blue","green"];
        }
    
        function SubType(){
        }
    
        //继承了SuperType
        SubType.prototype = new SuperType();
    
        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors);    //red,blue,green,black
    
        var instance2 = new SubType();
        alert(instance2.colors);    //red,blue,green,black

    2.借用构造函数(伪造对象/经典继承)

    基本思想:在子类型构造函数的内部调用超类型构造函数。函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在(将来)新创建的对象上执行构造函数。

        function SuperType(){
            this.colors=["red","blue","green"];
        }
    
        function SubType(){
            //继承了SuperType
            SuperType.call(this);  //“借调”了超类型的构造函数
        }
    
        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors);    //red,blue,green,black
    
        var instance2 = new SubType();
        alert(instance2.colors);    //red,blue,green

    我们实际上是在(未来将要)新创建的SubType实例的环境下调用了SuperType构造函数,这样一来,就会在新SubType对象上执行SubType函数中定义的所有对象初始化代码。结果,SubType的每个实例就都会具有自己的colors属性的副本了。

    问题:方法都在构造函数中定义,函数复用无从谈起。而且,在超类型的原型中定义的方法对子类型不可见。

    3.组合继承(伪经典继承)

    思路:使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承。

        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",29);
        instance1.colors.push("black");
        alert(instance1.colors);
        instance1.sayName();
        instance1.sayAge();
    
        var instance2 = new SubType("Greg",27);
        alert(instance2.colors);
        instance2.sayName();
        instance2.sayAge();
  • 相关阅读:
    Oracle Grid 11.2.0.4 安装是出现“[INS-41112] Specified network interface doesnt maintain connectivity across cluster”错误
    复旦大学2018--2019学年第二学期(18级)高等代数II期末考试第七大题解答
    复旦大学2018--2019学年第二学期(18级)高等代数II期末考试第八大题解答
    复旦大学高等代数在线课程2018--2019学年记录
    凝心聚力、创建一流 —“综合性高校高等代数课程教学研讨会”在复旦举行
    复旦高等代数II(18级)每周一题
    复旦大学高等代数在线课程2018--2019学年学习情况分析及文字评教信息
    复旦大学2018--2019学年第一学期高等代数I期末考试情况分析
    复旦大学2018--2019学年第一学期(18级)高等代数I期末考试第七大题解答
    复旦大学2018--2019学年第一学期(18级)高等代数I期末考试第八大题解答
  • 原文地址:https://www.cnblogs.com/alexandra/p/3655872.html
Copyright © 2011-2022 走看看