3

我有两个类和一个如下所示的接口。快速总结:接口 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) (this instanceof Winterface) 返回 true 但是

2) this.hello 是 88 岁吗?如果 this.hello = 88,那么 this = Big,它不是 Winterface 的一个实例。

我不明白这是怎么可能的,在此先感谢

编辑:谢谢大家我现在明白'this'指的是little,这是一个Big并实现Winterface。由于该方法被称为 super.theMethod(),因此可用的变量“hello”是 Big 中的变量,即使“this”指的是 little。

4

5 回答 5

2

lis Littlebut Littleis aBig 并且还实现了 的行为Winterface
super是对父类的调用,因此使用了父类的hello成员(即Big)。
你没有这样做this.hello,但super.theMethod()它使用了类的成员变量hello

更新:
调用父类中 的super.theMethod()相应方法。在父类中,您访问父类的字段(也属于派生类,因为Little也是 a Big)。因此this.hello,此时正在访问属于父类的代码部分。
你可以想象一下内存打印Little如下:

++++++++
+ Big  +
--------
+Little+
++++++++  

Little父 ie 的所有成员变量也是如此Big,当代码在super.theMethod()其中运行时,它在Big.
正如彼得在他的回答中所说,方法不支持多态,我希望这种过于简单的描述有助于理解这一点

于 2012-07-31T15:35:27.800 回答
2

this只能是一类。但是this.hello,该类可以访问该字段。

因为this只能是一个类,它是一个Little具有父级Big并实现的类,Winterface当您在其父级中调用一个方法时,它只能看到hello它所看到的。

即Java 支持方法的多态性,但不支持字段。

于 2012-07-31T15:35:46.390 回答
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
    ...
}

请注意,这种技术只能谨慎使用。

于 2012-07-31T15:38:46.113 回答
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 变量。

于 2012-07-31T15:40:08.657 回答
0

这里发生的情况是,当您在其中定义变量hello时,Little您并没有覆盖其中的变量hello,而是在Big其中定义了一个新变量helloLittle该变量将隐藏helloBig. 因此,在 的范围内Bighello将引用整数值 88,在 的范围内Littlehello将引用 true。这些都是包含在您的对象中的不同变量,唯一的区别是您引用它们的范围。

就像这里的其他人所说的那样,instanceof它是一个比较对象的运行时类型(返回的内容this.getClass())的运算符。Big即使在您的对象中的变量范围将引用 时,Bigthis仍然是运行时类型Little,这就是为什么它是Winterface.

于 2012-07-31T15:53:26.683 回答