Javascript 从ES6中的父类调用子方法
从父类调用子方法是好的还是坏的做法Javascript 从ES6中的父类调用子方法,javascript,ecmascript-6,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 { auto
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();
最好在父类中定义一个空的autoPlay实现,并在子类中重写它
class Parent {
constructor() {
this.autoPlay();
}
autoPlay() {
}
}
class Child extends Parent {
autoPlay() {
console.log('Child');
}
}
const child = new Child();
从父类调用子方法是一种好的做法吗
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();
是的,这是完全正常的做法。父类只调用实例的某个方法,如果子类重写了该方法,则调用子方法。然而,您通常不会进行这样一个“has my instance defined this method”测试,您只需要调用它。如果默认情况下不想执行任何操作,只需定义一个空方法(如@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 = song;
}
play(x) {
console.log(x+"playing "+this.song+" from ChildB");
}
}
const child1 = new ChildA();
child1.autoPlay();
const child2 = new ChildB("'Yeah'");
child2.autoPlay();
请注意,如果父级
构造函数调用了自动播放
,那么这将不起作用。如果您不想在实例化后到处需要额外的方法调用,请使用helper函数。它甚至可能是一种静态方法:
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'");
是的,父类与子类没有契约,相反。此外,将该方法移到父类中也没有意义。@LucasSteffen,每个扩展“parent”的类都有自己的“autoPlay”实现。因此,不可能将该方法移动到父级class@AliMamedov是否要求每个孩子都定义它?在这种情况下,您应该在父级中实现它,但会抛出一个错误。类似于
autoPlay(){throw new Error('autoPlay must implemented');}
。通常,从构造函数调用重写的方法不是一个好主意,因为您会遇到一系列初始化顺序问题。最佳实践是不从构造函数调用任何方法,而只进行实例初始化。创建实例的调用方应调用任何副作用,如autoplay
。(否则,可以这样调用重写的方法,尽管您通常不需要“if defined”检查)子类应该有自己的构造函数。不,这不是一个好的实践,除非类遵循一些接口,比如init
方法。。也许这就是原因。或者是帽子\_(ツ)_/'
不确定为什么会被否决。这是一个很好的示例。(+1来自我)在这种情况下,父类
被称为抽象类定义(抽象,因为它本身实例化可能没有用处)。它提供方法的通用定义/接口,但不是所有方法的实现,并期望派生类完成实现。这是一种正常的面向对象设计技术,允许多个派生类在父类中共享一组实现,在某些情况下,父类本身从未被它本身。是否应该从构造函数调用autoPlay()
是一个单独的问题。这行正确吗?this.song=this;
还是应该是?this.song=song
@SimonPuente您完全正确。感谢您的注意!Blast--所以如果我说,您有一个“getDefaultSettings()”我希望能够重写的方法,我将无法从抽象类构造函数调用它来适当地填充设置?(有意义,只是确保我完全正确)@sliftygetDefaultSettings
听起来它可能是一个静态方法,然后应该可以工作。它不能依赖于完全初始化的实例。