我怀疑this
在继承时JavaScript和Java是不同的行为。
在java中:
class Animal {
public String name = "animal";
void hello() {
System.out.println("hello " + this.name);
}
}
class Dog extends Animal {
public String name = "dog";
}
public class Main {
public static void main(String...args) {
Dog dog = new Dog();
dog.hello(); // hello animal
}
}
上面的代码将输出hello animal
,似乎当我在子类Dog的实例中调用hello方法时,它将在父类Animal中输出name属性。
但它在Javascript中有所不同:
class Animal {
constructor() {
this.name = 'animal';
}
hello() {
console.log('hello ' + this.name);
}
}
class Dog extends Animal {
constructor() {
super();
this.name = 'dog';
}
}
const dog = new Dog();
dog.hello(); // hello dog
如您所见,具有相同逻辑输出的代码会产生不同的结果。在JavaScript代码中,hello方法输出hello dog
,它是子类实例的名称属性。
我也尝试使用Python和C ++,结果是Python的行为与JavaScript类似,而C ++的行为与Java类似。
那是因为JavaScript和Python是动态语言吗?但是有什么细节以及为什么它们被设计成这个?
我应该读哪本书来了解它?
非常感谢,原谅英语不好......
答案 0 :(得分:1)
答案 1 :(得分:1)
在C ++和Java中,只有函数可以是虚拟的(即动态查找)。而在Python和JavaScript中,动态查找所有属性/属性/字段。据推测,C ++和Java不希望语言承诺超过可以用零开销或低开销实现。而Python和JavaScript不太关心开销,而更关心的是使语言能够满足您的需求。
如果您希望C ++的行为与JavaScript类似,那么您必须编写一个虚拟访问器函数来访问相应的字段。
class Animal {
string name_;
public:
Animal() : name_ {"animal"} {
}
virtual string name() const {
return name_;
}
void hello() {
cout << "hello " << name();
}
};
class Dog : public Animal {
string name_;
public:
Dog() : name_ {"dog"} {
}
string name() const override {
return name_;
}
};
int main() {
Dog dog;
dog.hello(); // hello dog
}