这个简单java程序的结果是什么?
现在在我的主课上这个简单java程序的结果是什么?,java,inheritance,Java,Inheritance,现在在我的主课上 public class NotActuallyImmutable { private final int x; public NotActuallyImmutable(int x) { this.x = x;// line 1 } public int getX() { return x; } } public class Mutable extends NotActuallyImmutable { private int x
public class NotActuallyImmutable {
private final int x;
public NotActuallyImmutable(int x) {
this.x = x;// line 1
}
public int getX() {
return x;
}
}
public class Mutable extends NotActuallyImmutable {
private int x = 123;
public Mutable(int x) {
super(x);
}
public int getX() {
return x++;
}
}
我期望输出为42,但它返回的输出为123。我期望42,因为在第2行,我使类的对象可变,然后在第1行,我将值设置为42。因此,当我执行
n.getX()
时,我应该得到这个最新值,而不是默认值123。我知道我遗漏了一些东西,但无法理解其背后的逻辑?问题是Mutable
中的x
字段和classnotallyimmutable
中的x
字段不一样。由getX()
返回的x
是Mutable
中的一个(因为调用的getX()
是Mutable.getX()
,而不是NotActuallyImmutable.getX()
)
请注意,如果从Mutable
中删除实例字段,则会出现编译器错误,因为NotActuallyImmutable.x
是NotActuallyImmutable
的私有字段,并且Mutable
中的任何代码都无法访问
如果将NotActuallyImmutable.x
设置为受保护的字段,则Mutable.x
将对其进行阴影处理,并且您仍然具有相同的行为。如果在本例中删除了Mutable.x
,仍然会出现编译器错误,因为您试图递增final
字段
如果删除
Mutable.getX()
,则getX()
返回的x
将是NotActuallyImmutable.x
,尽管在Mutable
中有另一个同名字段,但Mutable
中的private int x
和notactualyimmutable
中的private int x
是完全不同的字段,它们只有相同的名称
这对编译器来说不是问题,因为您无法从另一个类访问private
字段。因此,就编译器而言,当您定义Mutable
时,NotActuallyImmutable
中的x
是不可见的,也可能不存在
这当然会让程序员感到困惑。如果将其中一个字段重命名为y
(将getter方法重命名为getY
),则行为看起来更直观
NotActuallyImmutable n = new Mutable(42); // line2
int x = n.getX();
System.out.println("x is"+x);
这意味着您有一个NotActuallyImmutable类型的对象,但所创建对象的实例是可变的。
因此,在这段代码中,您将处理将返回123的可变对象。由于您传递的数字保存为NotActualYimmutable而非Mutable,
n
有两个不同的x
值,它们在不同的上下文中可见,即父类的私有成员变量和子类的私有成员变量
NotActuallyImmutable n = new Mutable(42); // line2
创建新的可变。执行将父类的x
设置为42的parent(x)
NotActuallyImmutable n = new Mutable(42); // line2
n
是一个Mutable
实例,因此调用Mutable
的getX()
,它返回Mutable
(123)的值,而不是父对象的值。我同意上面答案中给出的很好的解释。只是简单介绍一下最后的理解。在我执行新的Mutable(42).getX()时,jvm将首先查找Mutable对象,以获取NotActuallyImmutable中没有的X值。如果我从Mutable中删除getX()方法,我会得到预期的值,即42
这个例子很混乱,因为变量名,即X在父类和子类中是相同的,但有助于理解概念您确定可以编译上面的代码吗?在这种情况下,我不会使用术语“阴影”。对我来说,“阴影”意味着如果第二个变量不存在,第一个变量可以访问,但在这种情况下,即使第二个变量不存在,你也无法访问第一个x
。@SamuelEdwinWard-是的,我在修复语言时看到你的注释弹出。
int x = n.getX();