zoukankan      html  css  js  c++  java
  • 继承

    继承

    • 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,实现继承则继承实际的方法。由于ES中函数没有签名(也是无重载的原因),无法实现接口继承,只支持实现继承。
    • 原型链:利用原型让一个引用类型继承另一个引用类型的属性和方法。
    • 构造函数、原型和实例三者关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针

    实现继承的方法

    • 父类

        //定义一个鸟类
        function Bird(name) {
            //属性
            this.name = name || 'Bird'
            //实例方法
            this.fly = function() {
                console.log(this.name + '正在飞!')
            }
        }
        //原型方法
        Bird.prototype.eat = function(food) {
            console.log(this.name + '正在吃' + food);
        };
      
    1. 原型链继承:将父类的实例作为子类的原型

       function Pigeon() {
           // 不能放到构造器
       }
       Pigeon.prototype = new Bird();
       Pigeon.prototype.name = 'Pigeon';
       //检测
       var pigeon = new Pigeon();
       console.log(pigeon.name);
       console.log(pigeon.fly());
       console.log(pigeon.eat(rice))
      
    • 缺点:
    1. 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
    2. 无法实现多继承
    3. 来自原型对象的引用属性是所有实例共享的,针对父类实例引用类型成员的更改,会通过影响其他子类实例
    4. 创建子类实例时,无法向父类构造函数传参
    1. 构造继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

       function Pigeon(name) {
           Bird.call(this);
           this.name = 'Pigeon' || name;
       }
       //检测
       var pigeon = new Pigeon();
       console.log(pigeon.name);
       console.log(pigeon.fly());//只能继承实例方法
       console.log(pigeon instanceof Bird);// false,不是父类的实例,只是子类的实例
      
    • 缺点:
    1. 实例并不是父类的实例,只是子类的实例
    2. 只能继承父类的实例属性和方法,不能继承原型属性/方法
    3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
    1. 组合继承:通过调用父类构造器,继承父类的属性并保留传参的有优点,然后将父类实例作为子类原型,实现函数复用

       function Pigeon(name) {
           Bird.call(this);//一份实例
           this.name = 'Pigeon' || name;
       }
       Pigeon.prototype = new Bird();//另一份实例
       Pigeon.prototype.constructor = Cat;//组合继承需要修复构造函数的指向
       //检测
       var pigeon = new Pigeon();
       console.log(pigeon.name);
       console.log(pigeon.fly());
      
    • 缺点:
    1. 调用了两次父类构造器,生成了两份实例
    1. 寄生组合继承:通过寄生方式,砍掉父类的实例属性,这样在调用两次父类构造函数的时候,就不会初始化两次实例方法/属性,避免了组合继承的缺点

       function Pigeon(name) {
           Bird.call(this);
           this.name = 'Pigeon' || name;
       }
       (function() {
           // 创建一个没有实例方法的类
           var Super = function() {};
           Super.prototype = Bird.prototype;
           // 将实例作为子类的原型
           Pigeon.prototype = new Super();
       })();
       Pigeon.prototype.constructor = Pigeon;//修复指向构造函数的指针
       //测试
       var pigeon = new Pigeon();
       console.log(pigeon.name);
       console.log(pigeon.fly());
       console.log(pigeon.eat(rice));
       console.log(pigeon instance of Pigeon);/true
       console.log(pigeon instance of Bird);//true
  • 相关阅读:
    什么是PostBack(译)
    GridView 多余字符显示省略号,并在Tooltip中显示完整信息
    GridView中添加行单击事件.md
    ASP.NET WebForm 通过 PagedDataSource 实现 Repeater 的分页
    回发或回调参数无效(译)
    jQuery UI Autocomplete Combobox 配 ASP.NET DropDownList
    6个重要的.NET概念:
    ASP.NET 使用Session,避免用户F5刷新时重复提交(转)
    支持行单击、双击事件的GridView和DataList控件(译)
    在TextBox中敲击回车执行ASP.NET后台事件
  • 原文地址:https://www.cnblogs.com/yfife/p/8630310.html
Copyright © 2011-2022 走看看