java - 为什么父类(super class)的实例变量没有被子类覆盖?

标签 java

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

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 中,只有方法可以被覆盖。

当您在父类(super class)中声明与现有字段同名的字段时,新字段隐藏现有字段。父类(super class)中的现有字段仍然存在于子类中,甚至可以使用...根据正常的 Java 访问规则。

(在您的示例中,C 的实例有两个不同的字段,称为 a,包含不同的值。)


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

他们为什么要这样设计?

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

    例如:

       public class Sup {
           private int foo;
           public int getFoo() {
               return foo;
           }
       }
    
       public class Sub extends Sup {
           private int[] foo;
           ...
       }
    

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

  2. 如果被覆盖的字段不是私有(private)的,那就更糟了。这将以非常基本的方式打破 Liskov 可替代性原则 (LSP)。这消除了多态性的基础。

  3. 另一方面,覆盖字段不会实现其他方式无法更好完成的任何事情。例如,一个好的设计将所有实例变量声明为私有(private),并根据需要为它们提供 getter/setter。 getter/setter可以被覆盖,并且父类可以通过直接使用私有(private)字段或声明 getter/setter final来“保护”自己免受不必要的覆盖。


引用资料:

关于java - 为什么父类(super class)的实例变量没有被子类覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12086298/

相关文章:

java - Java8-Streams 中的 GroupingBy

Xmonad 中不显示 Java Swing GUI

java - Java 中数据规范化的拼写更正

java - React native ANDROID 构建失败并在 BasePackageList.java 中出现错误。可变参数不匹配; ApplicationPackage 无法转换为 Package

Java 字符串与枚举的匹配

java - Java 中不正确的模数结果

java - 这是调车院的错还是我的错?

java - 无法将 Spring 方面设置为最低顺序

java - 设置 JTextField 设置

java - JPanel中按钮的居中对齐