• 面向对象设计——继承


    序:回顾构造函数、原型和实例之间的关系

    每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

    1.原型链

    function Super(){
        this.property = true;
    }
    Super.prototype.getSuperValue = function(){
        return this.property;
    };
    
    function Sub(){
        this.subproperty = false;
    }
    Sub.prototype = new Super();  //给原型添加方法的代码一定要放在替换原型的语句之后
    //添加新方法
    Sub.prototype.getSubValue = function(){
        return this.subproperty;
    };
    //重写超类型的方法
    Sub.prototype.getSuperValue = function(){
        return false;
    }
    var instance = new Sub();
    alert(instance.getSuperValue());  //false 

    缺点:

    (1)引用类型的原型实例会被所有实例共享。

    (2)子类不能向超类传递参数。

    2.借用构造函数

    function Super(name){
        this.name = name;
    }
    function Sub(){
        //继承了Super,同时还传递了参数
        Super.call(this, "Nicholas");
        //实例属性
        this.age = 29;
    }
    var instance = new Sub();
    alert(instance.name);  //"Nicholas"
    alert(instance.age);   //29

    缺点:无法避免构造函数存在的问题——方法都在构造中定义,因此函数复用就无从谈起了。

    3.组合继承(常用)

    将原型链和借用构造函数组合到一块

    function Super(name){
        this.name = name;
        this.colors = ["red","blue","green"];
    }
    Super.propotype.sayName = function(){
        alert(this.name);
    };
    function Sub(name,age){
        //继承属性
        Super.call(this, name);   //第二次调用Super
        this.age = age;
    }
    //继承方法
    Sub.prototype = new Super();  //第一次调用Super
    Sub.prototype.constructor = Sub;
    Sub.propotype.sayAge = function(){
        alert(this.age);
    };
    
    var instance1 = new Sub("Nicholas",29);
    instance1.colors.push("black");

    缺点:会两次调用父类型的构造函数。

    4.原型式继承

    必须有一个对象作为另一个对象的基础。

    ECM5通过新增Object.create()方法规范了原型式继承。这个方法接收两个参数:一个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。

    function object(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
    var person = {
        name: "Nicholas",
        friends: ["Shelby","Court","Van"]
    };
    var anotherPerson = object(person);
    anotherPerson.friends.push("Rob");
    alert(person.friends);  //"Shelby,Court,Van,Rob"

    优势:不想兴师动众的创建构造函数,只想一个对象与另一个对象保持相似的情况下,原型式可以完全胜任。

    缺点:属性共享。

    5.寄生式继承

    function createAnother(original){
        var clone = object(original);  //object()函数不是必须的,任何返回新对象的函数都可以
        clone.sayHi = function(){
            alert("hi");
        };
        return clone;
    }
    var person = {
        name: "Nicholas",
        friends:["Shelby","Court","Van"]
    };
    var anotherPerson = createAnother(person);
    anotherPerson.sayHi();  //"hi"

    6.寄生组合式继承(最理想的继承范式)

    原理:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非是一个超类型原型的副本。

    function inheritPrototype(subType, superType){
        var prototype = object(superType.prototype);
        prototype.constructor = subType;
        subType.prototype = prototype;
    }
    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;
    }
    inheritPrototype(SubType, SuperType);
    SubType.prototype.sayAge = function(){
        alert(this.age);
    }
  • 相关阅读:
    洛谷P1724 东风谷早苗
    hdu 1001 Sum Problem
    洛谷 P1006 传纸条
    codevs 6116 区间素数
    LibreOJ #101. 最大流
    洛谷 P1455 搭配购买
    LibreOJ #119. 最短路 (堆优化dijkstra)
    LibreOJ #109. 并查集
    COGS.1200 ganggang的烦恼
    uoj #15. 【NOIP2014】生活大爆炸版石头剪刀布
  • 原文地址:https://www.cnblogs.com/lixuemin/p/5708309.html
Copyright © 2020-2023  润新知