我有一个关于Java继承和转换的问题.我有以下两个示例类和一个测试类,我在类之后陈述我的问题:
public class Automobile { public int var; public Automobile () { var = 1; } public String toString () { return "AUTOMOBILE: " + var; } } public class Porsche extends Automobile { public int var; public Porsche () { var = 2; } public String toString () { return "PORSCHE: " + var; } } public class Test { public static void main (String [] args) { Porsche p = new Porsche(); Automobile a = new Automobile(); System.out.println ("(Automobile) p = " + (Automobile)p); System.out.println ("(Automobile) p.var = " + ((Automobile)p).var); } }
输出是:
(Automobile) p = PORSCHE: 2 (Automobile) p.var = 1
我不明白为什么在第二个声明中我们有1.它不应该是2吗?因为我在第一个声明中将p转换为汽车之后我仍然得到PORSCHE: 2
了p
- 我通过以下方式理解:
尽管如此,我仍然将p
汽车p
保留为"原始性质" - p
是保时捷的一个对象,但由于保时捷延伸了汽车,我们可以说p也是汽车.因此,当我们将它明确地转移到汽车时,它会继续使用它的方法 - 在我们的例子toString()
中是保时捷中定义的方法.
另一方面,如果我写的是正确的,那么第二个print语句应该给2而不是1.
现在这似乎与我相矛盾,但由于这在Java中起作用,似乎我不明白在转换和继承过程中发生了什么.
我相信你实际上无法覆盖Java中的变量.子类实际上"隐藏"了变量var
.
当你转换为Automobile
,你得到var
变量的超类'版本.但是,该toString()
方法仍然在查看实例的var
变量版本.
如果您public int var
从保时捷子类中删除它,它应该按预期工作.
应该注意的是,使用公共实例变量并不是一种好的做法,您应该始终创建getter/setter以进行适当的封装.
隐藏变量var
.
你Porche.var
的变量不同于Automobile.var
.
该Porsche.toString()
方法使用Porsche.var
,而演员告诉编译器使用该Automobile
版本.