與面向類的語言相比,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