Javascript ES6(节点8.4.0和最新的Chrome和最近的Firefox)
我期待
class Parent {
init(){
console.log("Parent init") ;
this._surname = "McClass" ;
}
constructor() {
console.log("Parent constructor") ;
this.init();
}
get surname(){
return this._surname ;
}
}
class Child extends Parent {
init(){
console.log("Child init") ;
}
constructor() {
super();
console.log("Child constructor") ;
this.init();
}
}
var child = new Child() ;
console.log(child.surname);
给出以下输出;
Parent constructor
Parent init
Child constructor
Child init
McClass
(这是可比的C ++代码给出的)
唉,我得到了这个;Parent constructor
Child init
Child constructor
Child init
undefined
我做错了什么或这是正确的预期行为,如果是这样,它是如何合理的?
修改;
请参阅下面的MinusFour的答案,了解如何实现我的目标/期望。
至于为什么观察到的输出是"正确"行为和合理;
正如Bergi所指出的那样(在评论中)所有对js中对象方法的调用都是有效的"虚拟" (该名称的最后一个方法添加到对象的原型继承链中,是第一个找到并因此执行的方法)。事实证明,在类构造环境中调用仍然是有效的。
C ++在构造期间不应用虚拟方法行为,但Java会再次使用类似的Java代码获得相同的输出(如上所述),因此观察到的行为有先例。
答案 0 :(得分:2)
你可以这样做:
Scanner sc = new Scanner(System.in);
System.out.println("\nEnter your color\n" +
"BLUE, BLACK, ORANGE, WHITE, YELLOW, RED, GREEN, PINK:");
String str = sc.next();
str = str.toUpperCase();
private ArrayList<Color> colorArray= new ArrayList<Color>();
// Here I want to put the colors (string str) in the colorArray arraylist.
Parent.prototype.init.call(this);
要确保它永远不会被覆盖,但我建议你不要首先覆盖它。
答案 1 :(得分:0)
这是预期的行为,因为它可以在遵循规范的已建立的ES6类实现中看到。
this
引用当前类实例,在实例化Child
的情况下是Child
的实例 - 即使在Parent
类中,因为只有一个实例,它是instanceof Child
。
如果Child
覆盖了该方法,则它有责任提供调用它的机制。考虑到init
遵循一些记录的约定,并且是为了使构造函数更精简和更可测试而进行类初始化的地方,它是:
class Parent {
init(){...}
constructor() {
this.init();
}
...
}
...
class Child extends Parent {
init(){
super.init();
...
}
// optional, as long as `init` contains all init logic
constructor() {
super();
}
}
结果如下:
Parent constructor
Parent init
Child init
Child constructor
如果init
应该在两个类中完全独立工作,则不应该覆盖它。方法的名称应不同,例如initParent
和initChild
。或者可以使用任何其他避免命名冲突的方法,例如:
const init = Symbol('Parent init');
class Parent {
[init](){...}
constructor() {
this[init]();
}
...
}
...
const init = Symbol('Child init');
class Child extends Parent {
[init](){...}
constructor() {
this[init](); // totally independent method
}
}