隐藏类的实例变量

tsk*_*zzy 15 java oop

我想知道为什么Java对于超类和具有相同名称的实例变量的子类有这种奇怪的行为.

假设我们有以下类定义:

class Parent {
    int var = 1;
}

class Child extends Parent {
    int var = 2;
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,我们应该隐藏超类的变量var.如果我们没有明确指定的方式来访问Parentvar通过super电话,那么我们不应该能够访问var一个孩子的一个实例.

但是当我们有一个演员表时,这个隐藏机制就会破坏:

Child child = new Child();
Parent parent = (Parent)child;
System.out.println(parent.var); // prints out 1, instead of 2
Run Code Online (Sandbox Code Playgroud)

这不完全绕过整个隐藏点吗?如果是这种情况,那么这不会使这个想法完全没用吗?

编辑:我在Java教程中专门提到这篇文章.它提到了

在子类中,超类中的字段不能通过其简单名称引用.相反,必须通过超级...访问该字段

从我在那里读到的内容,似乎暗示Java的开发人员在这方面考虑了某种技术.虽然我同意这是一个相当模糊的概念,但总的来说可能是不好的做法.

NPE*_*NPE 19

在Java中,数据成员不是多态的.这意味着,Parent.varChild.var 是碰巧有相同名称的两个不同的变量.你var在派生类中没有任何意义上的"重写" ; 正如您自己发现的那样,这两个变量可以彼此独立地访问.

最好的前进方式取决于你想要实现的目标:

  1. 如果Parent.var不应该看到Child,那就去做吧private.
  2. 如果Parent.varChild.var是两个逻辑上不同的变量,给他们不同的名字,以避免混淆.
  3. 如果Parent.varChild.var逻辑上是相同的变量,那么为它们使用一个数据成员.


Jon*_*eet 6

字段隐藏的"要点"仅仅是指定代码的行为,该代码确实为变量提供与其超类中的变量相同的名称.

它并不意味着被用作真正隐藏信息的技术.这是通过将变量设为私有来完成的......我强烈建议在几乎所有情况下都使用私有变量.字段是一个实现细节,应该对所有其他代码隐藏.