What does Java `this` actually refer to in an inheritance situation?
为什么下面的Java代码产生:
1 2 | 10 superclass |
问题代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | class SuperClass { int a; public SuperClass() { this.a = 10; } private void another_print() { System.out.println("superclass"); } public void print() { System.out.println(this.a); this.another_print(); } } class SubClass extends SuperClass { int a; public SubClass() { this.a = 20; } private void another_print() { System.out.println("subclass"); } public void print() { super.print(); } } public class Main { public static void main (String[] args) { SubClass c = new SubClass(); c.print(); } } |
号
没有创建过
让我们考虑一个类似的python代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class SuperClass: def __init__(self): self.a = 10 def another_prn(self): print('superclass') def prn(self): print(self.a) self.another_prn() class SubClass(SuperClass): def __init__(self): self.a = 20 def another_prn(self): print('subclass') def prn(self): super().prn() c = SubClass() c.prn() |
它按我的预期工作:
1 2 | 20 subclass |
。
我的同事(Python不喜欢Java人)提出的唯一解释是:"Python不是真正的OOP语言"。一点也不令人信服。
更新:
它是Java中构造函数调用的顺序。在
现在我们已经完成了
很明显,我们称之为
在子类的print中,您只需调用super类的print方法。当然,它是从超级班打印A的。
这里有两个独立的A字段。字段不受重写的约束,只有方法受重写。超级类有一个A字段,子类中有另一个A字段。
如果另一种语言产生了另一种结果,那不是什么大惊喜。此外,我不确定您的Python代码在逻辑上等同于/类似于Java代码。
我的评论解释了您的代码可能无法按预期工作的原因。下面是您最有可能期望它工作的代码。注意代码中的注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | static class SuperClass { int a; // only declare field in superclass to avoid hiding public SuperClass() { this.a = 10; } // make method protected, public, or package private to allow children to override it protected void another_print() { System.out.println("superclass"); } public void print() { System.out.println(this.a); this.another_print(); } } static class SubClass extends SuperClass { public SubClass() { this.a = 20; } @Override protected void another_print() { System.out.println("subclass"); } public void print() { super.print(); } } public static void main (String[] args) { SubClass c = new SubClass(); c.print(); } |
这将打印
1 2 | 20 subclass |
号
我调试了稍微更正的代码,发现:
this is a reference to the current object — the object whose method or constructor is being called
号
我想我可以接受这样一个事实:EDCOX1×21将拥有整个依赖树的所有变量,而Java将根据上下文选择使用哪一个。