我不明白'this'与超类一起使用

时间:2012-07-31 15:31:52

标签: java oop inheritance interface polymorphism

我有两个类和一个如下所示的界面。 快速摘要:界面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'指的很少。

5 个答案:

答案 0 :(得分:2)

lLittle,但LittleBig 也实现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中,即使对象中的变量范围将引用Bigthis仍然是运行时类型Little,这就是为什么它是{的实例{1}}。