美文网首页
JS中类的继承封装和多态

JS中类的继承封装和多态

作者: 空压机百科 | 来源:发表于2020-02-28 01:51 被阅读0次

    子类继承父类的属性和方法(原生继承,call继承,寄生组合继承,ES6中class类继承)
    原生继承:让子类的原型指向父类的一个实例

    function A(){this.x = 100;}
    A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
    function B(){this.y = 200;}
    B.prototype = new A();
    var f = new B();
    
    原型图

    1、方式:B.prototype = new A();A的实例本身具有父类A的私有属性和公有方法,子类B的原型指向它,那么子类B的实例就可以找到这些属性和方法
    2、和传统后台语言继承不一样,子类继承父类,并不是把父类属性和方法克隆一份给子类,JS中的原型继承是让子类和父类建立原型链的机制。
    存在问题:子类可以重写父类原型上的方法(重写),子类和父类还是有关系
    父类的私有属性和公有属性都变为了子类实例的公有属性
    子类原型上的属性和方法,重新执行父类实例后,之前的方法都没有了类的继承封装和多态

    call继承:把父类A作为普通函数执行,让A中的 this 变为B的实例,相当于给B的实例增加一些属性和方法

    function A(){this.x = 100;}
    A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
    function B(){A.call(this);this.y = 200;}   //让A执行,让A中的this变为f
    var f = new B();
    

    存在问题:把父类A当作普通函数执行,和父类原型没关系,只是把A中的私有属性变为子类B实例的私有属性,A原型上的公有属性方法和B以及它的实例没有关系

    寄生组合继承:A的私有变为B的私有,A的公有变为B的私有

    function A(){this.x = 100;}
    A.prototype = {constructor: A, getX: function () {console.log(this.x);}};
    function B(){A.call(this);this.y = 200;}  //基于call把A的私有变为B的私有
    //B.prototype = A.prototype;  //一般不这样处理,这种模式可以轻易修改父类原型的上的东西,会导致A的实例也受影响
    B.prototype = Object.create(A.prototype);
    var f = new B();
    
    原型图

    这种方法和原型继承的唯一区别:
    B.prototype = new A() 创建的A的实例虽然指向了A的原型,但是实例中不是空的,存放了A的私有属性,这些属性成为了B的公有属性
    B.prototype = Object.create(A.prototype)好处是创建了一个没有任何私有属性的空对象,指向A的原型,这样B的公有属性中不会存在A的私有属性
    扩展:Object.create():内置Object类自带方法的作用:
    1、创建一个空对象
    2、让新建的空对象的__proto__指向第一个传递进来的对象(把传递进来的对象做为新创建的空对象的原型)

    ES6中的类和继承:
    ES6创建类标准语法,这种语法创建出来的类只能 new 执行,不能作为普通函数执行

    class Fn{
        constructor(n,m) {
            // 等价于传统ES5类的构造体
            this.x = n;
            this.y = m;
        };
        getX(){}; // 给Fn的原型上设置方法(只能设置方法不能设置属性)
        static AA(){}; // 把Fn当作普通对象设置私有方法,不能设置属性
    }
    let f = new Fn(10,20);
    

    继承方法:

    class A{constructor() {this.x = 100;};getX(){}}
    class B extends A{constructor() {super();this.y = 200;};getY(){}} // 类似于call继承,super中传递的实参都是给A的constructor传递
    let f = new B()
    
    • 封装:把实现一个功能的代码进行封装,主要目的是‘低耦合高内聚
    • 多态:
      a、重载:方法名相同,参数的个数或者类型不同,名字相同的方法叫做重载(后台语音中才有重载),JS中不能存在重载
      b、重写:字类重写父类方法
      c、继承

    相关文章

      网友评论

          本文标题:JS中类的继承封装和多态

          本文链接:https://www.haomeiwen.com/subject/ssuqhhtx.html