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();
  • 相关阅读:
    【11.5】生成器进阶--send、close和throw方法
    【11.4】协程是什么?
    【python】IO多路复用(select、poll、epoll)介绍及select、epoll的实现
    【11.3】select+回调+事件循环获取html
    【11.2】C10K问题和io多路复用(select、poll和epoll)
    【11.1】并发、并行、同步、异步、阻塞、非阻塞
    【10.10】进程间通信--Queue、Pipe、Manager
    set autotrace on 报cannot set autotrace 错误解决方法
    通配符获取文件
    日期函数
  • 原文地址:https://www.cnblogs.com/alexandra/p/3655872.html
Copyright © 2011-2022 走看看