ES6 Class 的继承(十一)

07-14 957阅读

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

ES6 Class 的继承(十一)
(图片来源网络,侵删)
class Point {
}
class ColorPoint extends Point {
}

继承的特性:

  • extends 关键字:使用 extends 来表示一个类继承自另一个类。
  • super 关键字:在子类的构造函数中使用 super() 调用父类的构造函数。
  • 方法重写:子类可以重写父类的方法。
  • 访问控制:子类可以访问父类的公共和受保护的成员,但不能直接访问私有成员。
  • 对象实例化:子类实例化时,首先执行父类的构造函数。
  • 原型链:子类的原型是父类的实例,子类继承了父类的原型链。

    继承的用法:

    1. 使用 extends 来实现继承。
    2. 在子类的构造函数中使用 super 调用父类的构造函数。
    3. 重写父类的方法以提供新的实现。
    4. 利用原型链的特性来实现方法的继承。

    1. 基本继承

    class Animal {
        constructor(name) {
            this.name = name;
        }
        speak() {
            return `${this.name} makes a noise.`;
        }
    }
    class Dog extends Animal {
        speak() {
            return `${this.name} barks.`;
        }
    }
    let dog = new Dog('Rex');
    console.log(dog.speak()); // 输出: Rex barks.
    

    2. 调用父类的构造函数

    class Rectangle {
        constructor(width, height) {
            this.width = width;
            this.height = height;
        }
        getArea() {
            return this.width * this.height;
        }
    }
    class Square extends Rectangle {
        constructor(sideLength) {
            super(sideLength, sideLength); // 调用父类的构造函数
        }
    }
    let square = new Square(5);
    console.log(square.getArea()); // 输出: 25
    

    3. 方法重写

    class Person {
        greet() {
            return 'Hello';
        }
    }
    class Student extends Person {
        greet() {
            return 'Hello, my name is ' + this.name;
        }
        introduce() {
            return `${this.greet()}, I am a student.`;
        }
    }
    let student = new Student();
    student.name = 'Alice';
    console.log(student.introduce()); // 输出: Hello, my name is Alice, I am a student.
    

    4. 访问父类的静态方法

    class Animal {
        static getClassName() {
            return 'Animal';
        }
    }
    class Dog extends Animal {
        static getClassName() {
            return super.getClassName() + ' (Dog)';
        }
    }
    console.log(Dog.getClassName()); // 输出: Animal (Dog)
    

    5. 原型链方法调用

    class Vehicle {
        start() {
            console.log('Vehicle is starting.');
        }
    }
    class Car extends Vehicle {
        start() {
            super.start(); // 调用父类的 start 方法
            console.log('Car is starting.');
        }
    }
    let car = new Car();
    car.start(); // 输出: Vehicle is starting. 然后 Car is starting.
    

    6. Object.getPrototypeOf 方法可以用来从子类上获取父类。

    Object.getPrototypeOf(ColorPoint) === Point
    // true
    

    可以使用这个方法判断,一个类是否继承了另一个类。

    7. 类的 prototype 属性和proto属性

    大多数浏览器的 ES5 实现之中,每一个对象都有 proto 属性,指向对应的构造函数的 prototype 属性。Class 作为构造函数的语法糖,同时有 prototype 属性和 proto 属性,因此同时存在两条继承链。

    • 子类的 proto 属性,表示构造函数的继承,总是指向父类。
    • 子类 prototype 属性的 proto 属性,表示方法的继承,总是指向父类的 prototype 属性。
      class A {
      }
      class B extends A {
      }
      B.__proto__ === A // true
      B.prototype.__proto__ === A.prototype // true
      
      //类的继承模式
      class A {
      }
      class B {
      }
      // B 的实例继承 A 的实例
      Object.setPrototypeOf(B.prototype, A.prototype);
      // B 继承 A 的静态属性
      Object.setPrototypeOf(B, A);
      const b = new B();
      

      8. 原生构造函数的继承

      原生构造函数是指语言内置的构造函数,通常用来生成数据结构。ECMAScript 的原生构造函数大致有下面这些。

      Boolean()

      Number()

      String()

      Array()

      Date()

      Function()

      RegExp()

      Error()

      Object()

      9. Mixin 模式的实现

      Mixin 指的是多个对象合成一个新的对象,新对象具有各个组成成员的接口。它的最简单实现如下。

      const a = {
        a: 'a'
      };
      const b = {
        b: 'b'
      };
      const c = {...a, ...b}; // {a: 'a', b: 'b'}
      
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]