【问题标题】:I do not understand 'this' being used with a superclass我不明白“this”与超类一起使用
【发布时间】:2012-07-29 10:21:33
【问题描述】:

我有两个类和一个如下所示的接口。 快速总结:接口 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 时,我得到以下输出

Big 在这里:是的,88 很少有人在这里:真的

我的问题是,怎么能

1) (this instanceof Winterface) return true but

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

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

编辑:感谢我现在理解的每个人,“this”指的是 little,它是 Big 并实现了 Winterface。由于该方法被称为 super.theMethod(),因此可用的变量 'hello' 是 Big 中的变量,即使 'this' 指的是 little。

【问题讨论】:

标签: java oop inheritance interface polymorphism


【解决方案1】:

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

由于this 只能是一个类,它是一个Little,它有一个父级Big 并实现Winterface 当你在它的父级中调用一个只能看到hello 的方法时,它看到的就是这个.

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

【讨论】:

  • 这并不能回答关于Winterface 的问题。
  • Java 支持方法多态,但不支持字段。谢谢,这基本上清除了它
【解决方案2】:

lLittleLittleBig 并且 也实现了 Winterface 的行为。
super 是对父类的调用,因此使用父类的hello 成员(即Big)。
你不是在做this.hello,而是super.theMethod(),它使用了父母的类成员变量hello

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

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

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

【讨论】:

  • 嗯?我在 super.theMethod() 中做 this.hello。 'this' 怎么能在同一个方法中引用两个不同的东西?
【解决方案3】:

这是因为this instanceof ...检查不使用静态(即编译时)类型(即Big),而是对象的(this')动态运行时类型(即@ 987654324@),在您的示例中为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
    ...
}

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

【讨论】:

    【解决方案4】:

    您的变量是 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 变量。

    【讨论】:

    • 我明白,但在那种方法中,“this”似乎对我来说既小又大。我现在明白了,这有点大,并且实现了winterface
    • “this”的类型取决于您在哪里调用“this”。对象本身当然是 Little,但此时运行的代码是 Big。因此,此时假定“this”为 Big,因为您正在运行 Big 的代码。 Big 没有 Little 的内置知识,因此不能将“this”视为 Little。
    【解决方案5】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-05-20
      • 2023-03-16
      • 2010-12-03
      • 2019-04-13
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2017-08-31
      • 2021-05-20
      相关资源
      最近更新 更多