解释这个问题,我们要分两块来解释
1. 解释super
super是java的一个关键字,其字面意思是指向父类的实例, 但是是一个很特殊的关键字(请先不要把它和this进行比较,它们不具有可比较性),只能出现下面三种方式。
- super.varname : 引用父类的变量, 如果子类定义了重名的父类变量,否则编译报错
public class Parent {
public int a = 11;
public int b = 12;
public Parent() {}
public void setVarA(int a) { this.a = a; }
public void setVarB(int b) { this.b = b; }
}
public class Child extends Parent {
public int a = 21;
public int c = 22;
public Child() { super(); }
public void setVarA(int a) { this.a = a; }
public void setVarC(int c) { this.c = c; }
}
- super.funname() : 引用父类的函数, 如果子类定义了重名的父类函数,否则编译报错
- super() : 在构造函数中调用父类的构造函数
public class Child extends Parent {
...
public void foo() {
System.out.printf("super.a=%d", super.a); // 11
System.out.printf(", this.a=%d\n", this.a); // 21
System.out.printf("super.b=%d", super.b); // 12
System.out.printf(", this.b=%d\n", this.b); // 12
//System.out.printf("super.c=%d", super.c); // compiler error
System.out.printf(", this.c=%d\n", this.c); // 22
super.setVarA(100);
super.setVarB(102);
//super.setVarC(102); // compiler error
System.out.printf("super.a=%d", super.a); // 100
System.out.printf(", this.a=%d\n", this.a); // 21
System.out.printf("super.b=%d", super.b); // 102
System.out.printf(", this.b=%d\n", this.b); // 102
//System.out.printf("super.c=%d", super.c); // compiler error
System.out.printf(", this.c=%d\n", this.c); // 22
}
}
因此super不能单独使用,比如
System.out.println(super); 编译器会报错, 尽管 System.out.println(this);是正确的代码。
2. 解释getClass
getClass 函数定义在Object基类里面:
public final native Class<?> getClass();
Returns the runtime class of this
这里明确说明了返回的是运行时刻创建实例的类类型;因为不管当前object是指向子类Child,还是基类Parent,他们对应的运行时实例都是Child类型,因为getClass的返回就是子类Child类型,因此
this.getClass()和super.getClass()指的同一个类实例, 即Child