与面向类的语言相比,JS基于原型,而对象的构造函数不仅包含“构造函数逻辑”(我在MDN中发现了这个术语),而且构造函数还定义了特权方法。在一个“类”是另一个类的孩子的情况下(遗憾的是,我不知道比JS的“类”更好的术语),这导致父类构造函数在子类能够覆盖之前执行的问题一个方法或者子类不能重写一个方法,因为构造函数还没有运行。Javascript:如何在覆盖子类中的继承方法之后运行父类的构造函数逻辑?
我会举一个例子来说明我的意思。假定在对象上定义了特权函数的“父类”以及调用此方法的构造函数逻辑。
function Parent() {
this.methodA = function() {
// do something
};
// C'tor logic starts here
// Beside other things also call some method of this object
this.methodA();
}
假设一个孩子的类,应重新定义methodA
但仍使用父类的构造函数 逻辑。
第一种方法是在 子构造函数的开头调用父构造函数。但是,父构造函数仍然调用父项的实现。
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
function Child() {
// Call parent constructor first. Problem: The parent constructor
// calls methodA before it will be overriden by child constructor
Parent.call(this);
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and then call parent method
_oldMethodA.call(this);
};
}
第二种方法是以后调用父构造,但是,然后 父方法不能被重写。
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
function Child() {
// Override first. Problem: The parent constructor has not defined methodA
// yet, hence the line below fails.
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and call parent method
_oldMethodA.call(this);
};
Parent.call(this);
}
如何交叉JS构造函数的两个任务 - 特权方法和构造函数逻辑的定义 - 按正确的顺序调用?
附录 - 附加材料,由于意见
我从评论想通了,它似乎并没有被清楚我想要什么。因此,这里是用Java编写的
class Parent {
public Parent() {
methodA();
}
public void methodA() {
System.out.println("I do the work of the parent's method");
}
}
class Child extends Parent {
public Child {
super();
}
public void methodA() {
System.out.println("I do the work of the child's method and ...");
super();
}
}
Parent p = new Parent();
Child c = new Child();
的例子这将导致下面的输出
$> I do the work of the parent's method
$> I do the work of the child's method and ...
$> I do the work of the parent's method
这是什么情况。 Parent
的构造函数调用Parent
中定义的methodA
的实现。这没什么特别的,并产生第一行输出。 Child
的构造函数只是调用父类的构造函数,它再次像以前那样调用methodA
。但是,尽管这是父级的构造函数,但该对象仍然是Child
的一个实例,因此将执行子级的methodA
的实现。此方法打印输出的第二行,然后显式调用生成第三行的父级方法。
根据OOP,这是完美的正确行为,这也是我想用Javascript实现的。所以它实际上是opposite of the problem mentioned here。链接来自评论。
哪里是'methodB'? – Ben
您的问题不是基于原型的继承或特权方法,而是从构造函数中调用可覆盖的方法。这在我见过的任何语言中都不太好。 – Bergi
@BenAston:对不起,'methodB'是评论中的一个错字。该示例的以前版本使用了两种方法,但我将MWE简化为一种方法。 – user2690527