这个问题是关于Java中super
和this
的实现决策。考虑
父类包含一个变量name
和一个方法getName()
public class Parent {
protected String name = "Parent";
protected String getName(){
return this.name;
}
}
子类继承父类,但有自己的name
变量
public class Child extends Parent {
protected String name = "Child";
protected void printNames() {
System.out.println("Parent: " + super.getName());
System.out.println("Child: " + this.getName());
}
public static void main(String[] args) {
Child c = new Child();
c.printNames();
}
}
输出:
Parent: Parent
Child: Parent
从输出中,我们可以看到: 当从具有super
上下文的 Child 类调用方法 getName()
时,它返回"Parent",但当使用this
上下文调用时,它再次返回"Parent"
如果该方法仅存在于 Parent 类中,但两者中都存在具有相同访问修饰符的数据成员,
为什么不应该从子类this.getName()
返回"Child",因为它is-a
父类因此具有getName()
作为其方法
更新这个问题不是关于如何打印或覆盖"子",而是关于核心Java团队this
的实现决策,以及它对他们的预期。
字段不是overridable
只有方法,字段只能隐藏或不隐藏。 this
实际上是指方法Parent#getName()
中类型为 Parent
的当前Object
,以便它将获得在 Parent
或潜在的父类中定义的变量名称的值,但不会在像 Child
这样的子类中。
下面是一个简单的代码片段,显示了这个想法:
Child child = new Child();
// Show the variable name of the class Child
System.out.println(child.name);
// Show the variable name of the class Parent which is what this.name
// does in the getName method
System.out.println(((Parent)child).name);
输出:
Child
Parent
得到'child'作为输出,你必须覆盖getname()方法,否则它是继承的,它将始终显示'parent'作为输出。
您需要向子类添加一个 getName() 方法。 现在,当您调用 this.getName() 时,将调用父版本,因为它在子类中未被覆盖。
只需重写 Child 类中的 getName()
方法
@Override
protected String getName() {
return name;
}
更新
如果您不想覆盖getName()
方法,可以这样做:
- 在
Child
构造函数中设置name
值,因为它是protected
属性 不再覆盖
Child
类中的name
属性public class Child extends Parent { public Child() { super(); this.name = "Child"; } // ... }