为什么超类的实例变量没有被子类覆盖? [英] Why is an instance variable of the superclass not overridden by a subclass?

查看:83
本文介绍了为什么超类的实例变量没有被子类覆盖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参见下面的代码,其中方法print被覆盖,但变量a没有被覆盖.为什么允许在子类中声明重复的变量?

See my code below, in which the method print is overridden but variable a is not. Why is it allowed to declare duplicate variables in a subclass?

class B {
    int a = 10;
    public void print() {
        System.out.println("inside B superclass");
    }
}

class C extends B {
    int a = 20;
    public void print() {
        System.out.println("inside C subclass");
    }
}

public class A {
    public static void main(String[] args) {
        B b = new C();
        b.print(); // prints: inside C subclass
        System.out.println(b.a); // prints superclass variable value 10
    }
}

推荐答案

为什么在子类方法中不重写超类的实例变量,请参见下面的代码...

Why instance variable of a superclass is not overridden in subclass method see my code below ...

因为实例变量不能在Java中覆盖.在Java中,只能重写方法.

Because instance variables CANNOT be overridden in Java. In Java, only methods can be overridden.

在声明与超类中现有字段同名的字段时,新字段会隐藏现有字段.父类中的现有字段仍然存在于子类中,甚至可以使用...遵守常规的Java访问规则.

When you declare a field with the same name as an existing field in a superclass, the new field hides the existing field. The existing field from the superclass is still present in the subclass, and can even be used ... subject to the normal Java access rules.

因为实例变量在Java中无法被覆盖,但是为什么呢?为什么在Java中以这种方式完成呢?是什么原因?

Because instance variables CANNOT be overridden in Java, but why? why is it done in this manner in Java? What's the reason?

他们为什么要这样设计?

Why did they design it that way?

  1. 因为覆盖变量将从根本上破坏超类中的代码.例如,如果重写更改了变量的类型,则很可能会更改在使用原始变量的父类中声明的方法的行为.在最坏的情况下,它使它们无法编译.

  1. Because overriding variables would fundamentally break code in the superclass. For example, if an override changes the variable's type, that is likely to change the behavior of methods declared in the parent class that used the original variable. At worst, it renders them uncompilable.

例如:

   public class Sup {
       private int foo;
       public int getFoo() {
           return foo;
       }
   }

   public class Sub extends Sup {
       private int[] foo;
       ...
   }

如果Sub.foo覆盖(即替换)Sup.foogetFoo()如何工作?在子类上下文中,它将试图返回错误类型的字段的值!

If Sub.foo overrides (i.e. replaces) Sup.foo, how can getFoo() work? In the subclass context, it would be trying to return a value of a field of the wrong type!

如果被覆盖的字段不是私有字段,那就更糟了.这将以一种非常根本的方式打破《里斯科夫可替代性原则》(LSP).这就消除了多态性的基础.

If fields that were overridden were not private, it would be even worse. That would break the Liskov Substitutability Principle (LSP) in a pretty fundamental way. That removes the basis for polymorphism.

在另一方面,覆盖字段将无法实现其他方法无法做到的任何事情.例如,一个好的设计将所有实例变量都声明为私有实例,并根据需要为其提供getter/setter方法.可以覆盖getter/setters ,并且父类可以通过直接使用私有字段或声明getters/setters final来保护"自身免受不希望的覆盖.

On the flipside, overriding fields would not achieve anything that cannot be done better in other ways. For example, a good design declares all instance variables as private and provides getters/setters for them as required. The getters/setters can be overridden, and the parent class can "protect" itself against undesirable overrides by using the private fields directly, or declaring the getters/settersfinal.


参考:


References:

  • Java Tutorial - Hiding Fields
  • JLS Example 8.3.1.1-3 - Hiding of Instance Fields.

这篇关于为什么超类的实例变量没有被子类覆盖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆