Javainheritance覆盖实例变量
我正在学习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
。
另一个疑问是,我理解隐藏方法,当父类中有静态方法时,子类也声明了具有相同签名的静态方法。 这里隐藏的意思? 什么方法被隐藏了? 如果它的父方法可以请你解释一下吗?
提前致谢。
-
无法在子类中重写Java实例变量。 Javainheritance不起作用。
-
在您的示例中,没有方法隐藏(或覆盖或重载)。
-
但是隐藏了实例变量。 在类
child
,a
的声明隐藏了parent
的声明,而child
类中对a
所有引用都引用了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
这表明有一个对象具有两个不同的字段,称为…,如果访问允许,您可以获取它们的两个值。
最后,您应该学会遵循标准的Java标识符约定。 类名应始终以大写字母开头。
Instance variables are not overriden in sub-class
。 如果在类中使用与超类中相同的名称定义变量,则称为变量的隐藏 inheritance and polymorphism
不适用于实例变量。 如果在父类中定义method()并在Child类中重写它。 由于运行时多态打印11 ,下面将调用Child的方法()
parent p1 = new child();
- 调用Child构造函数
- 使用super()调用invoke的父级构造函数
- 打印“在父级中”并将父级a初始化为10
-
打印在子项中并初始化Childs a到11
p1.method();// this invokes Child's method() during run-time
因为你没有在子类中重写method(),当声明时,
parent p1 = new child();
执行时,将执行method()的父版本,并且父类已知的唯一值是它自己的a。 因此它将打印a = 10(因为它当时在堆栈上)。
最后,您只是将变量a从父类映射到子类。
当你这样做
父P1 =新Child();
JVM做的是什么
first Initialize Parent() || second Initialize Child()
因此,首先调用Parent构造函数然后调用child,但输出值将为11,因为p1指的是child的对象。
问题是您创建了一个子实例并将其存储在父实例的引用中。 因此,当您访问对象的属性时,JVM引用父级的变量值。
如果它本来是一个子类的引用变量,你就会收到子类的变量值。
以上是Java的一个特性。
在创建父实例时。 所以在运行时编译器调用父对象,尝试下面的代码。
public static void main(String args[]) throws IOException { child c1 = new child(); c1.method(); }