为什么在继承中不覆盖超类的实例变量?
答案 0 :(得分:28)
您可以隐藏字段,但不能覆盖。
隐藏意味着字段将具有不同的值,具体取决于它所访问的类。子类中的字段将“隐藏”超类中的字段,但两者都存在。
隐藏字段是一种非常糟糕的做法,但有效:
public class HideField {
public static class A
{
String name = "a";
public void doIt1() { System.out.println( name ); };
public void doIt2() { System.out.println( name ); };
}
public static class B extends A
{
String name = "b";
public void doIt2() { System.out.println( name ); };
}
public static void main(String[] args)
{
A a = new A();
B b = new B();
a.doIt1(); // print a
b.doIt1(); // print a
a.doIt2(); // print a
b.doIt2(); // print b <-- B.name hides A.name
}
}
根据方法是否覆盖,访问A
或B
中的字段。
永远不要这样做!这绝不是您问题的解决方案,并且会创建与继承相关的非常微妙的错误。
答案 1 :(得分:25)
因为继承旨在修改行为。通过方法暴露行为,这就是为什么可以覆盖它们。
字段不是行为而是状态。您不需要修改它,也不需要修改超类使用的私有方法。它们旨在允许超类做它的工作。
答案 2 :(得分:1)
由于:
它可能会破坏parent class
代码。例如,如果允许实例变量重写,请考虑以下代码(以下代码中的行obB.getInt();
的行为):
class A
{
int aInt;
public int getInt()
{
return aInt;
}
}
class B extends A
{
int aInt;
public int getInt2()
{
return aInt;
}
public static void main(String[] args)
{
B obB = new B();
//What would be behavior in following line if,
//instance variables overriding is allowed
obB.getInt();
}
}
它不是逻辑,因为child class
应该/ {反映 parent class
的所有行为。
因此,您只能隐藏 child class
中的继承方法/变量,但不能override
。
以下内容摘自Java doc from Oracle,指明您可以执行/期望child class
的操作:
您可以按原样使用继承的成员,替换它们,隐藏它们或用新成员补充它们:
- 可以直接使用继承的字段,就像任何其他字段一样。
- 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)。