我想我已经有一段时间了解Java了,我缺乏一些基本概念。这是我要运行的代码:
class A{
int x =10;
void al(){
System.out.println("From a");
}
}
class B extends A{
int x = 20;
void al(){
System.out.println("From b");
}
public static void main(String args[]){
A obj = new B();
B obj1 = new B();
A obj2 = new A();
System.out.println(obj.x);
obj.al();
System.out.println(obj1.x);
System.out.println(obj2.x);
}
}
这是输出:
10
From b
20
10
当我尝试调用函数 al 时,它将调用 B 类中的函数。在这里发生简单的覆盖。 Obj尝试首先在基类中找到,然后在超类中找到。 现在,当我尝试通过对象 obj 访问“ X”时,它显示为“ 10”。 为什么它不显示“ 20”?
答案 0 :(得分:4)
您的问题特别是似乎是“为什么System.out.println(obj.x);
会打印10张而不是20张?”
obj
被声明为A
,因此obj.x
将始终解析为x
中存在的字段A
。字段没有dynamic dispatch。
最终,您的问题是Java中没有覆盖任何字段。超类中的字段仅获得hidden。当您声明
class A {
int x = 10;
}
class B extends A{
int x = 20;
}
并实例化一个B
,您返回的对象实际上包含两个整数。它们具有相同的名称的事实基本上是偶然的,并且使得独立地引用它们稍微有些困难,这通常就是为什么您应该选择不同的名称的原因。
答案 1 :(得分:2)
您不能覆盖属性,因为您可以覆盖方法。尽管实例的类型为BAx,并且实例的类型为BAx,Bx是两个不同的属性,并且无论如何都没有关联,但是A.al()被B.al()覆盖了。 >
答案 2 :(得分:1)
实例variables
无法被覆盖。它们是在编译时解析的,而不是 instance方法。