Java继承 - 实例变量重写

时间:2010-03-17 16:57:44

标签: java

为什么在继承中不覆盖超类的实例变量?

3 个答案:

答案 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
    }
}

根据方法是否覆盖,访问AB中的字段。

永远不要这样做!这绝不是您问题的解决方案,并且会创建与继承相关的非常微妙的错误。

答案 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 的操作:

  

您可以按原样使用继承的成员,替换它们,隐藏它们或用新成员补充它们:

     
      
  • 可以直接使用继承的字段,就像任何其他字段一样。
  •   
  • 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)。
  •