[英]What does Java `this` actually refer to in an inheritance situation?
为什么以下Java代码会产生:
10
superclass
有问题的代码是:
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();
}
}
没有创建SuperClass
实例,不是吗? 不仅Java开始寻找从SuperClass
调用的方法,它甚至以某种方式知道a = 10
!
让我们考虑类似的Python代码:
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()
它按预期工作:
20
subclass
我的同事(Python不喜欢Java人员)提出的唯一解释是:“Python不是真正的OOP语言”。 根本不是很有说服力。
更新: private void another_print()
是我的错误,我应该使用protected
。
在子类的打印中,您只需调用超类的打印方法。 所以它当然是从超级类打印出来的。
这里有两个单独的字段。 字段不受覆盖,只有方法。 超类有一个字段 ,你有另一个在子类中的字段。
如果另一种语言产生另一种结果,那不是一个大惊喜。 此外,我不确定您的Python代码在逻辑上是否等同于/类似于您的Java代码。
它是用Java调用的构造函数的顺序。
在SubClass
,当您实例化c
,构造函数隐式调用SuperClass
的默认构造SuperClass
( public SuperClass()
)(它必须这样做)。 然后在SuperClass
a
设置为10。
现在我们已经完成了SuperClass
构造函数,我们回到SubClass
的构造函数,它指定a = 20
。 但字段不受制于Java的重写,所以a
在SuperClass
仍是10。
之后很明显,我们调用c.print()
来调用SubClass
的print
,它调用SuperClass
的print
(通过super.print()
),打印a
你记得的10。然后是another_print
(这是没有被覆盖,因为它是private
)只是打印superclass
,我们已经完成。
我的评论解释了您的代码可能无法按预期工作的原因。 下面是代码,写下你最有可能期望它如何工作。 请注意代码中的注释。
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();
}
这将打印
20
subclass
我调试了稍微纠正过的代码并发现:
this
是SubClass
一个实例 a
来自SubClass
,第二个来自SuperClass
(作为隐式超类构造函数调用,再次与Python不同) this.a
有不同的值test_super()
和test_sub()
这是神奇的,因为this
是一个SubClass
和Java文件内容如下:
this
是对当前对象的引用 - 正在调用其方法或构造函数的对象
我认为我可以忍受这样一个事实: this
将包含整个依赖树的所有变量,Java将根据上下文选择使用哪一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.