我知道这种行为,但我不能 100% 确定为什么会发生这种情况。
我知道java中的实例变量没有多态性。变量由编译器静态解析。
但是在下面我对一些事情感到困惑:
class Animal{
String name = "Animal";
public void display(){
System.out.println("My name is "+ name);
}
}
public class Dog extends Animal {
String name = "Dog";
public static void main(String[] args) {
Animal a = new Dog();
Dog d = new Dog();
System.out.println(a.name);//Line 1
a.display();//Line 2
d.display();//Line 3
}
}
我知道Line 1它会显示Animal为静态类型a(由编译器解析)。
让我困惑的是为什么Line 3还会显示My name is Animal?
将尝试调用该方法,Dog因为这是运行时的实际对象,并且由于它没有被覆盖,因此将在父类中找到该方法Animal。
我不明白的是name,display如果实际操作的对象是Dog. 它不会隐藏父母的name变量吗?在我看来,它似乎不是静态解析的,因为类型是Dog. 它不是对象内存布局的一部分吗?
就像里面display只有父变量是可见的。为什么?
更新:
@Razvan 和 @LouisWasserman 的回答很有帮助。
在这些之后我有最后一个问题:
两者的观点似乎如下:
来自@Razyan
System.out.println("My name is "+ this.name); //<-- note the this
来自@Louis
that the refer thisto Animaland that the implementation of display() is in the Animal class。
到目前为止还可以。display()但是这些点如何与我修改如下 的事实一致:
class Animal{
String name = "Animal";
public void display(){
System.out.println("Current class is "+ this.getClass().getName());
System.out.println("My name is "+ name);
}
}
那么结果:
Dog d = new Dog();
d.display();
当前班级是狗
我的名字是动物
我期待this里面display会是Animal我在这里理解的答案。但事实并非如此。为什么?