Copyright©Stonee
1. this
在Java中,无论程序员是否在实例方法中添加,编译器都会自动往实例方法中加入一个this参数,this参数的类型为方法所在类的类型。
- 假设说fun() 是类中的一个方法,当调用这个方法的时候,编译器会把它变为this.fun() 然后通过this去找到fun所在的类。在这之前,当this被检测到时会被压栈,等到找到fun方法后,会把this出栈然后再传回去,形成:fun(this)
- 这也就是为什么当我们在用构造方法时可以使用this的原因,举个栗子:
package chapter05;
/**
* This program demonstrates "this" in Java
* @version 1.0 2019-3-27
* @author stonee(http://www.stonee.club)
*/
public class thisAndFunc {
public static void main(String [] args){
f a = new f();
a.func();
}
}
class f{
String name;
public void func(){ //this被作为参数传入func中,因为this是类f的类型,所以可以通过this调用f的字段,即this.name
this.name = "Wang";
System.out.println(name);
}
}
大家再思考这么一个问题,如果父类中有a和b两个函数,a调用了b函数,此时子类覆盖了b函数,那么在子类中,a函数是调用父类b函数还是子类覆盖的b函数呢?如下:
class A {
public void f(){
System.out.println("A::f()");
}
public void ff(){
f();
}
}
class B extends A {
public void f(){
System.out.println("B::f()");
}
}
public class Test {
public static void main(String args[]) {
B b = new B();
A ab = b;
b.f();
b.ff();
ab.f();
ab.ff();
}
}
运行结果是四个B::f()
答案显而易见。原因也是因为ff()在调用f()时,f()会变成this.f(),而this的返回值是它所在的类,即B,因此B中继承的ff()会调用自己的f()。
2. super
super和this的共同之处是都可以被编译器自动添加,但是this是本类的类型,但是super是基类的类型。
super有两种常见的用法:
① 调用父类构造方法 super(参数);
② 调用父类一般方法 super.func(参数);
因为根类是object,所以编译器在编译的时候会把构造方法中自动添加一个super();用来继承根类构造方法。
如果根类中没有没有参数的构造方法,那么这个程序是不能编译运行的,是因为编译器会自动给子类加上一个super(),因为自动加入的这个super方法时无参的,所以就需要父类中有一个无参的构造方法才行。