this和super关键字
this关键字
this的含义
this代表当前对象
this使用位置
- this在实例初始化相关的代码块和构造器中:表示正在创建的那个实例对象,即正在new谁,this就代表谁
- this在非静态实例方法中:表示调用该方法的对象,即谁在调用,this就代表谁。
- this不能出现在静态代码块和静态方法中
this使用格式
(1)this.成员变量名
- 当方法的局部变量与当前对象的成员变量重名时,就可以在成员变量前面加this.,如果没有重名问题,就可以省略this.
- this.成员变量会先从本类声明的成员变量列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员变量列表中查找
(2)this.成员方法
- 调用当前对象的成员方法时,都可以加"this.",也可以省略,实际开发中都省略
- 当前对象的成员方法,先从本类声明的成员方法列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员方法列表中查找
(3)this()或this(实参列表)
-
只能调用本类的其他构造器
-
必须在构造器的首行
-
如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(【实参列表】)",否则会发生递归调用死循环
super关键字
super的含义
super代表当前对象中从父类的引用的资源
super使用的前提
- 通过super引用父类的xx,都是在子类中仍然可见的(不是私有化的)
- 不能在静态代码块和静态方法中使用super(与this相同)
super的使用格式
(1)super.成员变量
在子类中访问父类的成员变量,特别是当子类的成员变量与父类的成员变量重名时。
public class Person {
private String name;
private int age;
//其他代码省略
}
public class Student extends Person{
private int score;
//其他成员方法省略
}
public class Test{
public static void main(String[] args){
Student stu = new Student();
}
}
public class Test{
public static void main(String[] args){
Son s = new Son();
s.test(30);
}
}
class Father{
int a = 10;
}
class Son extends Father{
int a = 20;
public void test(int a){
System.out.println(super.a);//10
System.out.println(this.a);//20
System.out.println(a);//30
}
}
(2)super.成员方法
在子类中调用父类的成员方法,特别是当子类重写了父类的成员方法时
public class Test{
public static void main(String[] args){
Son s = new Son();
s.test();
}
}
class Father{
public void method(){
System.out.println("aa");
}
}
class Son extends Father{
public void method(){
System.out.println("bb");
}
public void test(){
method();//bb
this.method();//bb
super.method();//aa
}
}
(3)super()或super(实参列表)
在子类的构造器首行,用于表示调用父类的哪个实例初始化方法
super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
就近原则和追根溯源原则
找变量
-
没有super和this
- 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量,
- 如果不是局部变量,先从当前执行代码的本类去找成员变量
- 如果从当前执行代码的本类中没有找到,会往上找父类的(非private,跨包还不能是缺省的)
-
this :代表当前对象
- 通过this找成员变量时,先从当前执行代码的本类中找,没有的会往上找父类的(非private,跨包还不能是缺省的)。
-
super :代表父类的
- 通过super找成员变量,直接从当前执行代码所在类的父类找
- super()或super(实参列表)只能从直接父类找
- 通过super只能访问父类在子类中可见的(非private,跨包还不能是缺省的)
注意:super和this都不能出现在静态方法和静态代码块中,因为super和this都是存在与对象中的
class Father{
int a = 10;
int b = 11;
}
class Son extends Father{
int a = 20;
public void test(){
//子类与父类的属性同名,子类对象中就有两个a
System.out.println("父类的a:" + super.a);//10 直接从父类局部变量找
System.out.println("子类的a:" + this.a);//20 先从本类成员变量找
System.out.println("子类的a:" + a);//20 先找局部变量找,没有再从本类成员变量找
//子类与父类的属性不同名,是同一个b
System.out.println("b = " + b);//11 先找局部变量找,没有再从本类成员变量找,没有再从父类找
System.out.println("b = " + this.b);//11 先从本类成员变量找,没有再从父类找
System.out.println("b = " + super.b);//11 直接从父类局部变量找
}
public void method(int a){
//子类与父类的属性同名,子类对象中就有两个成员变量a,此时方法中还有一个局部变量a
System.out.println("父类的a:" + super.a);//10 直接从父类局部变量找
System.out.println("子类的a:" + this.a);//20 先从本类成员变量找
System.out.println("局部变量的a:" + a);//30 先找局部变量
}
public void fun(int b){
System.out.println("b = " + b);//13 先找局部变量
System.out.println("b = " + this.b);//11 先从本类成员变量找
System.out.println("b = " + super.b);//11 直接从父类局部变量找
}
}
public class TestInherite2 {
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.a);//20
System.out.println(son.b);//11
son.test();
son.method(30);
son.fun(13);
}
}