- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
请参阅下面的代码,其中方法 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?
他们为什么要这样设计?
因为覆盖变量会从根本上破坏父类(super class)中的代码。例如,如果覆盖更改了变量的类型,则很可能会更改在使用原始变量的父类中声明的方法的行为。在最坏的情况下,它会使它们无法编译。
例如:
public class Sup {
private int foo;
public int getFoo() {
return foo;
}
}
public class Sub extends Sup {
private int[] foo;
...
}
如果 Sub.foo
覆盖(即替换)Sup.foo
,getFoo()
如何工作?在子类上下文中,它会尝试返回错误类型的字段的值!
如果被覆盖的字段不是私有(private)的,那就更糟了。这将以非常基本的方式打破 Liskov 可替代性原则 (LSP)。这消除了多态性的基础。
另一方面,覆盖字段不会实现其他方式无法更好完成的任何事情。例如,一个好的设计将所有实例变量声明为私有(private),并根据需要为它们提供 getter/setter。 getter/setter可以被覆盖,并且父类可以通过直接使用私有(private)字段或声明 getter/setter final
来“保护”自己免受不必要的覆盖。
引用资料:
关于java - 为什么父类(super class)的实例变量没有被子类覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12086298/
我是一名优秀的程序员,十分优秀!