Java 继承 - 实例变量覆盖

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2464222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 21:17:53  来源:igfitidea点击:

Java Inheritance - instance variables overriding

java

提问by sgokhales

Why are Instance variables of a superclass not overidden in Inheritance ?

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

回答by ewernli

You can hidea field, but not overrideit.

您可以隐藏字段,但不能覆盖它。

Hiding means that a field will have a different value depending from which class it's accessed. The field in the subclass will "hide" the field in the super-class, but both exists.

隐藏意味着一个字段将具有不同的值,具体取决于它访问的类。子类中的字段会“隐藏”超类中的字段,但两者都存在。

That's an extremely bad practice to hide field, but works:

隐藏字段是一种非常糟糕的做法,但有效:

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

Depending on whether the method was overriden, the field in Aor Bis accessed.

根据方法是否被覆盖,访问A或 中的字段B

Never do that!That's never the solution to your problem and creates very subtle bugs related to inheritance.

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

回答by extraneon

Because inheritance is intended to modify behaviour. Behaviour is exposed through methods, and that's why they can be overridden.

因为继承旨在修改行为。行为通过方法公开,这就是它们可以被覆盖的原因。

Fields are not behaviour but state. You don't need to modify that, nor the private methods employed by the superclass. They are intended to allow the superclass to do it's job.

字段不是行为而是状态。您不需要修改它,也不需要修改超类使用的私有方法。它们旨在让超类完成它的工作。

回答by cse

Because:

因为:

  • It may break the parent classcode. For example consider following code(What would be behavior of line obB.getInt();in following code if, instance variables overridingis allowed):

    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(); 
        }
    }
    
  • It is not logicalbecause child classshould have/reflect all behavioursof parent class.

  • 它可能会破坏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

So, you can only hidethe inherited methods/variables in child classbut can't override.

因此,您只能隐藏继承的方法/变量,child class但不能override

Following is an extract from Java doc from Oraclespecifying what operation you can perform/expect from child class:

以下是来自 Oracle 的 Java 文档的摘录,指定了您可以执行/期望的操作child class

You can use the inherited members as is, replace them, hide them, or supplement them with new members:

  • The inherited fields can be used directly, just like any other fields.
  • You can declare a field in the subclass with the same name as the one in the superclass, thus hiding it (not recommended).

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

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