我有一个关于 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 转换为 Automobile 之后,我仍然得到PORSCHE: 2
作为代表p
- 我的理解如下:
尽管如此我已经投了p
到汽车p
保持其“本性”——p
是 Porsche 类的对象,但因为 Porsche 扩展了 Automobile,所以我们可以说 p 也是一个 Automobile。因此,当我们将其显式转换为 Automobile 时,它会继续使用其方法 - 在
我们的案例方法toString()
保时捷定义的。
另一方面,如果我写的是正确的,那么第二个 print 语句应该给出 2 而不是 1。
现在这对我来说似乎是矛盾的,但由于这在 Java 中有效,所以我似乎不明白在转换和继承过程中发生了什么。
我相信你实际上不能覆盖 Java 中的变量。子类实际上“隐藏”了变量var
.
当你投射到Automobile
,您将获得超类版本var
多变的。但是,那toString()
方法仍在查看实例的版本var
多变的。
如果您删除了public int var
从保时捷子类来看,它应该按预期工作。
应该注意的是,使用公共实例变量不是一个好习惯,您应该始终创建 getter / setter 以具有适当的封装 http://home.cogeco.ca/~ve3ll/jatutor4.htm.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)