Call a child method from a parent class in ES6

2020-02-06 05:38发布

Is It good/bad practice to call a child method from a parent class?

class Parent {
    constructor() {
        // if 'autoPlay' exists (was implemented) in chain
        if (this.autoPlay) {
            this.autoPlay(); // execute from parent
        }
    }
}

class ChildA extends Parent {
    autoPlay() {
        console.log('Child');
    }
}

class ChildB extends Parent {
    // 'autoPlay' wasn't implemented
}

const childA = new ChildA();
const childB = new ChildB();

2条回答
家丑人穷心不美
2楼-- · 2020-02-06 06:03

It would be better style to define an empty implementation of autoPlay in the Parent class, and override it in the child.

class Parent {
  constructor() {
    this.autoPlay();
  }

  autoPlay() {

  }
}

class Child extends Parent {
  autoPlay() {
    console.log('Child');
  }
}

const child = new Child();
查看更多
可以哭但决不认输i
3楼-- · 2020-02-06 06:04

Is it a good practice to call a child method from a parent class?

Yes, it's a totally normal practise. The parent class just calls some method of the instance, and if the child class has overridden the method then the child method is called. However, you usually wouldn't do such a "has my instance defined this method" test, you just would call it. If you want to do nothing by default, just define an empty method (like in @scipper's answer). If you want to make the method abstract (force child classes to override it), you can either leave it undefined or define a method that throws an appropriate exception.

Is is a bad practice to call a child method from a parent constructor?

Yes. Don't do that. (It's a problem in all languages).

The purpose of a constructor is to initialise the instance and nothing else. Leave the invocations of side effects to the caller. This will ensure that all child constructors will finish their initialisation as well.

A contrived example:

class Parent {
    autoPlay() {
        this.play("automatically "); // call child method
    }
    play(x) {
        console.log(x+"playing default from "+this.constructor.name);
    }
}

class ChildA extends Parent {
    // does not override play
}
class ChildB extends Parent {
    constructor(song) {
        super();
        this.song = this;
    }
    play(x) {
        console.log(x+"playing "+this.song+" from ChildB");
    }
}

const child1 = new ChildA();
child1.autoPlay();
const child2 = new ChildB("'Yeah'");
child2.autoPlay();

Notice how that would not work if the Parent constructor did call autoplay. If you don't like to need an extra method call everywhere after the instantiation, use a helper function. It might even be a static method:

class Parent {
    autoPlay() { … }
    play { … }
    static createAndAutoPlay(...args) {
        const instance = new this(...args);
        instance.autoPlay();
        return instance;
    }
}
…
const child1 = ChildA.createAndAutoPlay();
const child2 = ChildB.createAndAutoPlay("'Yeah'");
查看更多
登录 后发表回答