从ES6中的父类调用子方法

Ali*_*dov 13 javascript ecmascript-6

从父类调用子方法是好/坏的做法?

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();
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 16

从父类调用子方法是一个好习惯吗?

是的,这是一种完全正常的做法.父类只调用实例的某个方法,如果子类重写了方法,则调用子方法.但是,你通常不会做这样的"我的实例定义了这个方法"测试,你只需要调用它.如果你想在默认情况下什么都不做,只需定义一个空方法(比如@ scipper的答案).如果要使方法成为抽象(强制子类重写它),可以将其保留为未定义或定义抛出适当异常的方法.

从父构造函数调用子方法是不好的做法?

是.不要那样做.(这是所有语言的问题).

构造函数的目的是初始化实例而不是其他任何东西.将副作用的调用留给调用者.这将确保所有子构造函数也将完成初始化.

一个人为的例子:

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();
Run Code Online (Sandbox Code Playgroud)

注意如果Parent构造函数调用它将如何工作autoplay.如果您不希望在实例化后需要额外的方法调用,请使用辅助函数.它甚至可能是一个静态方法:

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'");
Run Code Online (Sandbox Code Playgroud)


sci*_*per 7

在Parent类中定义autoPlay的空实现并在子类中覆盖它将是更好的样式.

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

  autoPlay() {

  }
}

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

const child = new Child();
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,`Parent` 被称为抽象类定义(抽象是因为它可能只是单独实例化没有用)。它提供了方法的通用定义/接口,但不是所有方法的实现,并期望派生类完成实现。这是一种普通的面向对象设计技术,它允许多个派生类在父类中共享一堆实现,并且在某些情况下,父类本身永远不会被自己使用。是否应该从构造函数调用 `autoPlay()` 是一个单独的问题。 (2认同)