当基类和派生类都具有相同名称的变量时会发生什么
考虑这些类中的
int a
变量:
class Foo {
public int a = 3;
public void addFive() { a += 5; System.out.print("f "); }
}
class Bar extends Foo {
public int a = 8;
public void addFive() { this.a += 5; System.out.print("b " ); }
}
public class test {
public static void main(String [] args){
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}
我知道方法addFive()
已在子类中被重写,并且在类测试中,当引用子类的基类引用用于调用重写方法时,调用子类版本addFive
。
但是公共实例变量ѭ4怎么样?当基类和派生类具有相同的变量时会发生什么?
上述程序的输出是
b 3
这是怎么发生的?
没有找到相关结果
已邀请:
4 个回复
炉挤仙挟
。 Foo对象有一个
变量。 Bar对象具有
和
变量。 当你运行这个:
方法更新
变量,然后读取
变量。要阅读
变量,您需要这样做:
这里发生的事情的技术术语是“隐藏”。有关示例,请参阅JLS第8.3节和第8.3.3.2节。 请注意,隐藏也适用于具有相同签名的
方法。 但是,具有相同签名的实例方法被“覆盖”而不是“隐藏”,并且您无法访问从外部覆盖的方法的版本。 (在覆盖方法的类中,可以使用
调用重写的方法。但是,这是唯一允许这样做的情况。通常禁止访问重写方法的原因是它会破坏数据抽象。) 避免混淆(意外)隐藏的推荐方法是将实例变量声明为
,并通过getter和setter方法访问它们。使用getter和setter还有很多其他好的理由。
糖固傻染
产生输出:
因为在类中声明了x 测试隐藏了x的定义 class Point,所以类Test没有 从它继承字段x 超类点。必须注意的是, 然而,那场x的场 class Point不是由类继承的 测试,它仍然实施 通过类Test的实例。其他 单词,Test的每个实例 包含两个字段,一个是int类型 和双重类型之一。这两个领域 承担名称x,但在 类测试声明,简单 name x总是指字段 在Test类中声明。代码 类Test的实例方法可以 引用实例变量x class Point as super.x。 使用字段访问的代码 表达式访问字段x将 访问类中名为x的字段 由参考类型表示 表达。因此,表达 sample.x访问一个double值,即 在类中声明的实例变量 测试,因为变量的类型 样本是Test,但是表达式 ((点)样本).x访问一个int value,声明的实例变量 在类Point中,因为强制转换为 键入点。
熊融炭臀陛
的工作原理。 现在,当调用
语句时,它实际上使用Base类的引用变量调用Derived类实例的'addFive()方法。所以最终调用'Bar'类的方法。但正如你所看到的'Bar'类的
方法只是打印'b'而不是'a'的值。 下一个语句,即
是实际打印最终被附加到前一输出的a的值,因此您将最终输出视为'b 3'。这里使用的值是'Foo'类的值。 希望这个技巧执行&编码很清楚,你明白你如何得到'b 3'的输出。
混侩闯空坷