我正在学习java。我对遗产有疑问。当子类扩展父类时,父类有一个方法引用父类中声明的实例变量。但是,子类dint会覆盖此方法,并声明了与父类同名的实例变量。在这种情况下,将引用来自child的实例变量或将引用parent。以下是代码段
class parent {
int a;
parent() {
System.out.println("in parent");
a = 10;
}
void method() {
System.out.println(a);
}
}
class child extends parent {
int a;
child() {
System.out.println("in child");
a = 11;
}
}
public class Test {
public static void main(String args[]) throws IOException {
parent p1 = new child();
p1.method();
}
}
我得到的输出是
父母中的
在孩子中
10
有人可以让我理解为什么它引用父类的实例变量a
而不是子类的a
。
另一个疑问是,我理解隐藏方法,当父类中有静态方法时,子类也声明了具有相同签名的静态方法。这里隐藏的意思?什么方法被隐藏了?如果它的父方法可以请你解释一下吗?
提前谢谢。
答案 0 :(得分:20)
无法在子类中重写Java实例变量。 Java继承不起作用。
在您的示例中,没有隐藏(或覆盖或重载)方法的方法。
虽然隐藏了实例变量。在课程child
中,a
的声明隐藏了a
中parent
的声明,以及a
类中对child
的所有引用到child.a
而不是parent.a
。
为了更清楚地说明这一点,请尝试运行:
public static void main(String args[]) throws IOException {
child c1 = new child();
parent p1 = c1;
System.out.println("p1.a is " + p1.a);
System.out.println("c1.a is " + c1.a);
System.out.println("p1 == c1 is " + (p1 == c1));
}
应输出:
p1.a is 10
c1.a is 11
p1 == c1 is true
这表明有一个对象有两个不同的字段,名为a
...如果访问允许,您可以获取它们的两个值。
最后,您应该学会遵循标准的Java标识符约定。类名应始终以大写字母开头。
答案 1 :(得分:2)
Instance variables are not overriden in sub-class
。如果在类中使用与超类中相同的名称定义变量,则称为变量的阴影 inheritance and polymorphism
不适用于实例变量。如果在父类中定义method()并在Child类中重写它。由于运行时多态打印 11
parent p1 = new child();
在子项中打印并将Childs a初始化为11
p1.method();// this invokes Child's method() during run-time
答案 2 :(得分:1)
当你这样做时
父P1 =新Child();
JVM做的是什么
first Initialize Parent()
||
second Initialize Child()
因此,首先调用Parent构造函数然后调用child,但输出值将为11,因为p1指的是子对象。
答案 3 :(得分:1)
因为你没有在子类中重写method(),所以语句
parent p1 = new child();
执行,将执行method()的父版本,并且父类已知的唯一值是它自己的a。因此它将打印a = 10(因为它在那个时候在堆栈上)。
最后,您只是将变量a从父类映射到子类。
答案 4 :(得分:0)
问题是您创建了一个子实例并将其存储在父实例的引用中。因此,当您访问对象的属性时,JVM引用父变量值。
如果它是一个子类的引用变量,你就会收到子类的变量值。
以上是Java的一个特性。
答案 5 :(得分:0)
创建父实例时。所以在运行时编译器调用父对象, 试试下面的代码。
public static void main(String args[]) throws IOException {
child c1 = new child();
c1.method();
}