Java中this和super关键字的使用方法(形似/不同,有史以来最详细)

this关键字

 

1、this的含义

this代表当前对象

2、this使用位置

  • this在实例初始化相关的代码块和构造器中:表示正在创建的那个实例对象,即正在new谁,this就代表谁

  • this在非静态实例方法中:表示调用该方法的对象,即谁在调用,this就代表谁。

  • this不能出现在静态代码块和静态方法中(因为this指的是对象,静态成员加载早于对象)

3、this使用格式

(1)this.成员变量名

  • 当方法的局部变量与当前对象的成员变量重名时,就可以在成员变量前面加this.,如果没有重名问题,就可以省略this.

  • this.成员变量会先从本类声明的成员变量列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员变量列表中查找

(2)this.成员方法

  • 调用当前对象的成员方法时,都可以加"this.",也可以省略,实际开发中都省略

  • 当前对象的成员方法,先从本类声明的成员方法列表中查找,如果未找到,会去从父类继承的在子类中仍然可见的成员方法列表中查找

(3)this()或this(实参列表)

  • 只能调用本类的其他构造器

  • 必须在构造器的首行

  • 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(【实参列表】)",否则会发生递归调用死循环

 

super关键字

 

1、super的含义

super代表当前对象中从父类的引用的

2、super使用的前提

  • 通过super引用父类的xx,都是在子类中仍然可见的

  • 不能在静态代码块和静态方法中使用super

3、super的使用格式

(1)super.成员变量

在子类中访问父类的成员变量,特别是当子类的成员变量与父类的成员变量重名时。

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() 都必须是在构造方法的第一行,所以不能同时出现。

 

就近原则和追根溯源原则

1、找变量

  • 没有super和this

    • 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的局部变量,

    • 如果不是局部变量,先从当前执行代码的本类去找成员变量

    • 如果从当前执行代码的本类中没有找到,会往上找父类的(非private,跨包还不能是缺省的)

  • this :代表当前对象

    • 通过this找成员变量时,先从当前执行代码的本类中找,没有的会往上找父类的(非private,跨包还不能是缺省的)。

  • super :代表父类的

    • 通过super找成员变量,直接从当前执行代码所在类的父类找

    • super()或super(实参列表)只能从直接父类找

    • 通过super只能访问父类在子类中可见的(非private,跨包还不能是缺省的)

注意:super和this都不能出现在静态方法和静态代码块中,因为super和this都是存在与对象中的

2、找方法

  • 没有super和this

    • 先从当前对象(调用方法的对象)的本类找,如果没有,再从直接父类找,再没有,继续往上追溯

  • this

    • 先从当前对象(调用方法的对象)的本类找,如果没有,再从父类继承的可见的方法列表中查找

  • super

    • 直接从当前对象(调用方法的对象)的父类继承的可见的方法列表中查找

3、找构造器

  • this()或this(实参列表):只从本类中,不会再往上追溯

  • super()或super(实参列表):只从直接父类找,不会再往上追溯

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);
	}
}

 

public class Test{
    public static void main(String[] args){
    	Son s = new Son();
    	System.out.println(s.getNum());//10   没重写,先找本类,没有,找父类
    	
    	Daughter d = new Daughter();
    	System.out.println(d.getNum());//20  重写了,先找本类
    }
}
class Father{
	protected int num = 10;
	public int getNum(){
		return num;
	}
}
class Son extends Father{
	private int num = 20;
}
class Daughter extends Father{
	private int num = 20;
	public int getNum(){
		return num;
	}
}
public class Test{
    public static void main(String[] args){
    	Son s = new Son();
    	s.test();
    	
    	Daughter d = new Daughter();
    	d.test();
    }
}
class Father{
	protected int num = 10;
	public int getNum(){
		return num;
	}
}
class Son extends Father{
	private int num = 20;
	public void test(){
		System.out.println(getNum());//10  本类没有找父类
		System.out.println(this.getNum());//10  本类没有找父类
		System.out.println(super.getNum());//10  本类没有找父类
	}
}
class Daughter extends Father{
	private int num = 20;
	public int getNum(){
		return num;
	}
	public void test(){
		System.out.println(getNum());//20  先找本类
		System.out.println(this.getNum());//20  先找本类
		System.out.println(super.getNum());//10  直接找父类
	}
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值