• Inheritance


    Implementing JavaScript inheritance using extends and super

    Prior to ES6, implementing a proper inheritance required multiple steps. One of the most commonly used strategies is the prototypal inheritance. The following illustrates how the Bird inherits properties from the Animal using the prototype inheritance technique.

    function Animal(legs) {
        this.legs = legs;
    }
    
    Animal.prototype.walk = function() {
        console.log('walking on ' + this.legs + ' legs');
    }
    
    function Bird(legs) {
        Animal.call(this, legs);
    }
    
    Bird.prototype = Object.create(Animal.prototype);
    Bird.prototype.constructor = Animal;
    
    
    Bird.prototype.fly = function() {
        console.log('flying');
    }
    
    var pigeon = new Bird(2);
    pigeon.walk(); // walking on 2 legs
    pigeon.fly(); // flying
    

    ES6 simplified these steps by using the extends and super keywords. The following example defines the Animal and Bird classes and establishes the inheritance through the extends and super keywords.

    class Animal {
        constructor(legs) {
            this.legs = legs;
        }
        walk() {
            console.log('walking on ' + this.legs + ' legs');
        }
    }
    
    class Bird extends Animal {
        constructor(legs) {
            super(legs);
        }
        fly() {
            console.log('flying');
        }
    }
    
    
    let bird = new Bird(2);
    
    bird.walk();
    bird.fly();
    

    In this example, the Bird‘s constructor uses super() to call the Animal‘s constructor with the specified arguments.

    Note that the class version is just the syntactic sugar for the prototypal inheritance. In other words, JavaScript uses classes for the syntax but still realizes on the prototype mechanism

    The Animal class is called base class and the Bird class is known as derived class. JavaScript requires the derived class to use super() if it has a constructor. As you see in the Bird class, the super(legs) is equivalent to the following statement.

    Animal.call(this, legs);
    

    If you decide to not use constructor in the Bird class, you can do it as follows:

    class Bird extends Animal {
        fly() {
            console.log('flying');
        }
    }
    

    It is equivalent to the following class:

    class Bird extends Animal {
        constructor(...args) {
            super(...args);
        }
        fly() {
            console.log('flying');
        }
    }
    

    However, if you specify the constructor, you muse call super() inside the constructor, therefore the following code results in an error.

    class Bird extends Animal {
        constructor(legs) {
        }
        fly() {
            console.log('flying');
        }
    }
    

    Because the super() initializes the this object, you must call the super() before accessing the this object. Trying to access this before calling super() results in an error.

    For example, if you want to initialize the color property of the Bird class, you can do it as follows:

    class Bird extends Animal {
        constructor(legs, color) {
            super(legs);
            this.color = color;
        }
        fly() {
            console.log('flying');
        }
        getColor() {
            console.log(this.color);
        }
    }
    
    
    let pegion = new Bird(2, 'white');
    console.log(pegion.getColor());
    

    Shadowing methods

    JavaScript allows you to add a new method in the derived class that has the same name as a method in the base class. In this case, when you call the method of an object of the derived class, that method will shadow the method in the base class.

    The following Dog class extends the Animal class and redefines the walk() method.

    class Dog extends Animal {
        constructor() {
            super(4);
        }
        walk() {
            console.log(`go walking`);
        }
    }
    
    let bingo = new Dog();
    bingo.walk(); // go walking
    

    To call the method of the base class in the derived class, you use super.method() like this:

    class Dog extends Animal {
        constructor() {
            super(4);
        }
        walk() {
            super.walk();
            console.log(`go walking`);
        }
    }
    
    let bingo = new Dog();
    bingo.walk();
    // walking on 4 legs
    // go walking
    

    Inheriting static members

    The derived class inherits all static members of the base class. See the following example.

    class Animal {
        constructor(legs) {
            this.legs = legs;
        }
        walk() {
            console.log('walking on ' + this.legs + ' legs');
        }
        static helloWorld() {
            console.log('Hello World');
        }
    }
    
    class Bird extends Animal {
        fly() {
            console.log('flying');
        }
    }
    

    In this example, the Animal class has the helloWorld() static method and this method is available as Bird.helloWorld() and behaves the same as the Animal.helloWorld() method. See the following code:

    Bird.helloWorld(); // Hello World
    

    Inheriting from built-in types

    JavaScript allows you to extend a built-in type such as Array, String, Map, and Set through inheritance. The following Queue class extends the Array reference type. The syntax is much cleaner than the Queue implemented using the constructor/prototype pattern.

    class Queue extends Array {
        enqueue(e) {
            super.push(e);
        }
        dequeue() {
            return super.shift();
        }
        peek() {
            return !this.empty() ? this[0] : undefined;
        }
        empty() {
            return this.length === 0;
        }
    }
    
    var customers = new Queue();
    customers.enqueue('A');
    customers.enqueue('B');
    customers.enqueue('C');
    
    while (!customers.empty()) {
        console.log(customers.dequeue());
    }
    

    In this tutorial, you have learned how to implement JavaScript inheritance using the extends and super keywords.

  • 相关阅读:
    c语言中 fgetc函数、fputc函数实现文件的复制
    c语言 13-7 利用fgetc函数输出文件的字符数
    c语言 13-6 利用fgetc函数输出文件的行数
    c语言中fgetc函数:显示文件内容
    c语言 13-5
    c语言 获取程序上一次运行时间的程序
    hzwer模拟赛 虫洞
    LYDSY热身赛 escape
    bzoj2330 糖果
    繁华模拟赛 Vicent坐电梯
  • 原文地址:https://www.cnblogs.com/PrimerPlus/p/12912150.html
Copyright © 2020-2023  润新知