我有两个类和一个如下所示的界面。 快速摘要:界面Winterface,Class Big,Class Little扩展Big并实现Winterface。
public interface Winterface {}
public class Big {
public int hello = 88;
public Big() {}
public void theMethod() {
System.out.println ("Big was here: " + (this instanceof Winterface) + ", " + this.hello);
}
}
public class Little extends Big implements Winterface{
private boolean hello = true;
public Little(){}
public void theMethod() {
super.theMethod();
System.out.println("Little was here: " + hello);
}
public static void main(String [] args) {
Little l = new Little();
l.theMethod();
}
}
当我在Little中执行main时,我得到以下输出
大在这里:是的,88 小小的在这里:真的
我的问题是,怎么可以
1)(这个Winterface实例)返回true但是
2)this.hello是88? 如果this.hello = 88,则this = Big,这不是Winterface的实例。
我不明白这是怎么回事,提前谢谢
编辑:感谢现在我理解的每个人'这个'指的是很少,这是一个Big并实现了Winterface。由于该方法被称为super.theMethod(),所以变量'hello'可用是Big中的变量,即使'this'指的很少。
答案 0 :(得分:2)
l
为Little
,但Little
为Big
,也实现Winterface
的行为。
super
是对父类的调用,因此使用父类的hello
成员(即Big
)。
您没有使用父级的类成员变量this.hello
super.theMethod()
而是hello
。
<强>更新强>
super.theMethod()
调用父类中的相应方法。在父类中,您可以访问父类的字段(它也属于派生类,因为Little
也是Big
)。因此,此时this.hello
正在访问父类的代码部分
你可以想象Little
的内存打印如下:
++++++++
+ Big +
--------
+Little+
++++++++
因此Little
具有父项的所有成员变量,即Big
,当代码在super.theMethod()
内运行时,它在Big
的“代码区域”内运行。
正如Peter在他的回答中所述,方法不支持多态性,我希望这种过于简单化的描述有助于理解这一点
答案 1 :(得分:2)
this
只能是一个班级。但是this.hello
是该类可以访问的字段。
由于this
只能是一个类,所以它是一个Little
,它有一个父Big
并实现Winterface
当你在其父级中调用一个只能看到的方法时hello
这就是它所看到的。
即。 Java支持方法的多态性,但不支持字段。
答案 2 :(得分:1)
这是因为this instanceof ...
检查不使用静态(即编译时)类型(Big
),而是对象的(this
')动态运行 - 时间类型(即this.getClass()
),在您的示例中为Little
。如果它将使用静态类型,那么运算符将是毫无意义的,因为我们将具有:
Object obj = "foo";
if (obj instanceof Object) { /* always entered */ }
/* but */ if (obj instanceof String) { /* never entered */ }
静态地,在编译时。 instanceof
运算符的目的是启用运行时类型测试,例如:
Object obj = /* whatever */;
if (obj instanceof String) {
String str = (String)obj; // Cast cannot fail
...
} else if (obj instanceof Long) {
Long val = (Long)obj; // Cast cannot fail
...
}
请注意,这项技术应该谨慎使用。
答案 3 :(得分:0)
你的变量是Big和Little的一个实例。它是Little的直接实例,但由于Little继承自Big,instanceof运算符也会为Big返回true。
Little l = new Little();
System.out.println(l instanceof Little); // true, l is an instance Little
System.out.println(l instanceof Big); // true, l is an instance of Little which inherits from Big
你的另一个误解(我假设)是“方法查找”的工作原理。当你调用theMethod时,它会选择Little的方法实现。当你调用super.theMethod时,你已经明确地说“调用Big方法版本的这个方法”,然后在那个方法中使用Big的hello变量而不是Little的hello变量。
答案 4 :(得分:0)
这里发生的事情是,当您在hello
中定义变量Little
时,您没有覆盖hello
内的变量Big
,而是定义了一个新变量hello
Little
中隐含变量hello
的{{1}}内的变量Big
。因此,在Big
的范围内,hello
将引用整数值88,并且在Little
的范围内,hello
将引用true。这些是对象中包含的不同变量,唯一的区别是您引用它们的范围。
像其他人所说的那样,instanceof
是一个运算符,用于比较对象的运行时类型(this.getClass()
返回的内容)。在Big
中,即使对象中的变量范围将引用Big
,this
仍然是运行时类型Little
,这就是为什么它是{的实例{1}}。