this关键字
含义:
- 存储的“当前对象”的引用。this代表当前对象。
this使用位置
- this在实例初始化相关的代码块和构造器中:表示正在创建的那个实例对象,即正在new谁,this就代表谁
- this在非静态实例方法中:表示调用该方法的对象,即谁在调用,this就代表谁。
- this不能出现在静态代码块和静态方法中
this关键字的三种用法
this访问本类成员变量: this.成员变量
- 当方法的局部变量与当前对象的成员变量重名时,就可以在成员变量前面加this.,如果没有重名问题,就可以省略this.
- this.成员变量会先从本类声明的成员变量列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员变量列表中查找
代码示例
public class Student{ String name = "张三"; public void show(){ String name = "李四"; System.out.println("name = " + name);// 李四 System.out.println("name = " + this.name);// 张三 } }
this访问本类成员方法: this.成员方法名( );
- 调用当前对象的成员方法时,都可以加"this.",也可以省略,实际开发中都省略
- 当前对象的成员方法,先从本类声明的成员方法列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员方法列表中查找
public class Student{ public void show(){ System.out.println("show方法..."); this.eat(); } public void eat(){ System.out.println("eat方法..."); } }
this访问本类构造方法 :this( )或this(实参列表)
- 只能调用本类的其他构造器
- 必须在构造器的首行
- 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(【实参列表】)",否则会发生递归调用死循环
public class Student { public Student() { this("张三",18); //调用指定的有参数构造 System.out.println("空参构造方法..."); } public Student(String name) { this();//当使用this()调用另一个构造方法时,此代码必须是此构造方法的第一句有效代码。 System.out.println("有参构造方法..."); } public Student(String name, int age){ System.out.println("有参构造方法..."+name+","+age); } }
super关键字
含义:
- super代表当前对象中从父类的引用的。可以理解为存储的“父类对象”的引用;
super使用的前提
- 通过super引用父类的xx,都是在子类中仍然可见的
- 不能在静态代码块和静态方法中使用super
super关键字的三种用法
super访问父类的成员变量: super.父类成员变量名
- 在子类中访问父类的成员变量,特别是当子类的成员变量与父类的成员变量重名时。
class Fu{ int num = 100; } class Zi extends Fu{ int num = 10; public void show(){ int num = 1; System.out.println("局部变量num:"+num);// 1 System.out.println("Zi 类中的num:"+this.num);// 10 //在子类中访问父类的成员变量,特别是当子类的成员变量与父类的成员变量重名时。 System.out.println("Fu 类中的num:"+super.num);// 100 } }
super访问父类的成员方法: super.成员方法名( );
- 在子类中调用父类的成员方法,特别是当子类重写了父类的成员方法时
class Fu{ public void method1(){ System.out.println("Fu method1..."); } } class Zi extends Fu{ public void show(){ // 访问父类的method1方法 super.method1(); } @Override public void method1(){ //在子类中调用父类的成员方法,特别是当子类重写了父类的成员方法时 super.method1();// 调用父类的method1方法 System.out.println("Zi method1..."); } }
super访问父类的构造方法:super()或super(实参列表)
- 在子类的构造器首行,用于表示调用父类的哪个实例初始化方法
class Fu{ public Fu(){ System.out.println("Fu 类的空参构造方法.."); } public Fu(String name, int age) { System.out.println("Fu 类的有参构造方法.."); } } public class Zi extends Fu{ public Zi(){ //在子类的构造器首行,用于表示调用父类的哪个实例初始化方法 super();// 调用父类的空参构造方法 System.out.println("Zi 类的空参构造方法.."); } public Zi(String name,int age){ super(name,age);// 调用父类的有参构造方法 System.out.println("Zi 类的有参构造方法.."); } }
总结:
- super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推...
- 子类的构造方法默认会调用父类的空参构造方法,如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错
- super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
就近原则和追根溯源原则
找变量
没有super和this
- 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量,
- 如果不是局部变量,先从当前执行代码的本类去找成员变量
- 如果从当前执行代码的本类中没有找到,会往上找父类的(非private,跨包还不能是缺省的)
存在this :
-
通过this找成员变量时,先从当前执行代码的本类中找,没有的会往上找父类的(非private,跨包还不能是缺省的)。
存在super
- 通过super找成员变量,直接从当前执行代码所在类的父类找
- super()或super(实参列表)只能从直接父类找
- 通过super只能访问父类在子类中可见的(非private,跨包还不能是缺省的)
注意:super和this都不能出现在静态方法和静态代码块中,因为super和this都是存在与对象中的
找方法
没有super和this
- 先从当前对象(调用方法的对象)的本类找,如果没有,再从直接父类找,再没有,继续往上追溯
存在this :
- 先从当前对象(调用方法的对象)的本类找,如果没有,再从父类继承的可见的方法列表中查找
存在super
- 直接从当前对象(调用方法的对象)的父类继承的可见的方法列表中查找
找构造器
- this()或this(实参列表):只从本类中,不会再往上追溯
- super()或super(实参列表):只从直接父类找,不会再往上追溯