解释java中this(this.及this())和super(super.及super())的使用

参考大佬的,拿小本子记下来。

目录

一、this

1、this .

2、this()

3、this 使用总结

二、super

1、super.

2、super()

三、总结


一、this

this 表示当前对象。

使用上细分的话,this有 this. 和this()的使用情况 。

1、this .

使用场景一: 在成员方法中,this.变量名 指带当前对象的变量,此时this.是可以省略的。

    public class Demo03 {
        int i;

    public void method(){
        this.i=3;
//      i=3  相当于this.i
    }


    public static void main(String[] args) {
        Demo03 demo03 = new Demo03(); //空构造生成对象,i为默认值0
        demo03.method(); //调用方法后,对i进行赋值 
        System.out.println(demo03.i);
    }
}

输出 结果为 “3” 。
在method()方法中,this.i=3 和i=3意思相同
但注意, 如果在method()方法中,输入的是 int i=3 结果可以完全不同。 为什么呢?
~~很显然。写成int i=3,这样做的意思是说在方法中,重新定义一个局部变量i,并非指代当前对象中的成员变量i。

使用场景二 : 在成员方法中,传入的参数名称和成员变量相同时,因java中变量的就近原则,使用this. 区分成员变量和传入值,此时this. 是不能省略的。

    public class Demo03 {
        int i;

    public void method(int i){
        this.i=i;
    }


    public static void main(String[] args) {
        Demo03 demo03 = new Demo03(); 
        demo03.method(3); 
        System.out.println(demo03.i);
    }
} 

输出 结果为 “3”。

但如果此时method方法中 不写成 this.i=i,而是写成 i=i(相当于,形参i向形参i赋值),这样本身其实没有意思,你要知道 ,形参(int i)会在栈中存储,这个变量会随着method方法弹栈后消亡,该形参int i和成员属性i之间是没有关系的。

ps: 场景二的情况是传参名和成员变量名相同,this. 才不可以省略,那起另一个名不就行了?

没错。完全可以起其它名字。 但是为了增强代码的可读性,一般将参数的名称和成员变量的名称保持一致,所以this的使用频率在规范的代码内部应该很多。

2、this()

在构造器中使用,构造器间相互调用。

class Person {
    private int age;
    private String name;
    Person() {}
    Person(String nm) {
        name = nm;
    }
    Person(String nm, int a) {
        this(nm);
        age = a;
    }
}

class PersonDemo {
    public static void main(String[] args) {
        Person p = new Person("张三", 23);
    }
}

说明:

1、先执行 main 方法,main 方法压栈,执行其中的 new Person(“张三”,23)。

2、堆内存中开辟空间,并为其分配内存地址 0x33,紧接着成员变量默认初始化(name=null age = 0)。
3、拥有两个参数的构造方法Person(String nm , int a)压栈,在这个构造
方法中有一个隐式的 this,因为构造方法是给对象初始化的,哪个对象调用到这个
构造方法,this 就指向堆中的哪个对象。

4、由于 Person(String nm , int a)构造方法中使用了 this(nm);构造方法
Person(String nm)就会压栈,并将“张三”传递给 nm。在 Person(String nm , int
a)构造方法中同样也有隐式的 this,this 的值同样也为 0x33,这时会执行其中
name = nm,即把“张三”赋值给成员的 name。当赋值结束后 Person(String nm)构造方法弹栈。

5、程序继续执行构造方法(Person(String nm , int a)中的 age = a;这时会
将 23 赋值给成员属性 age。赋值结束构造方法Person(String nm , int a)弹栈。

6、当构造方法Person(String nm , int a弹栈结束后,Person 对象在内存
中创建完成,并将 0x33 赋值给 main 方法中的 p 引用变量。
 

3、this 使用总结

在类的方法定义中使用的 this 关键字代表使用该方法的对象的引用。

this 即”自己”,代表对象本身,谁调用代表谁。在成员方法中或构造器中隐式的传递。作用如下:

1、this.属性,这样的表示方法,能够有效表示类中的成员属性,区分成员属性和形参。

2、this([实参列表]):在构造方法的首行,为了调用其他构造方法(构造方法中不能出现其他构造方法名,想实现构造方法调用构造方法,只能使用this([实参列表]))。

3、this 可以看作是一个变量,它的值是当前对象的引用,可以作为返回值。

4、this 不能出现在被 static 修饰的内容中。

二、super

super 有两种使用情况,super.及super()。

1、super.

当父类 和 子类 存在相同的成员属性或者成员方法,为区分这两种成员属性或者成员方法,会使用 super. 来指代父类中的成员属性或者成员方法。或者说 super. 存在的意义就是为了调用父类中隐藏的属性和方法。(构造器间的相互调用,放到2来讲)

public class Father {
	int age;
	String name;
	
    public Father(int age) {
        super(); //隐式
        this.age = age;
        System.out.println("我是father带参空构造");
    }

    public Father() {
        this(39);
        System.out.println("我是father空构造");

    }
    
    public void happySay(){
    	System.out.println("再接再厉");
    }
    
    private void sadSay(){
    	System.out.println("该努力学习了");
    }
}
public class Son extends Father {
	
	int age;
    public Son(int age) { 
        System.out.println("son带参构造");
    }	    
    public Son() { 
    	this(3);
    	System.out.println("son空参构造");  
    }
    public void happySay(){
    	System.out.println("奥利给!");
    }
    
    public void sonSay(){
    	this.happySay(); //public类型,可以被子类继承,可以被调用
    	//this.sadSay(); private类型,不能被子类继承,不能被调用
    	
    	super.happySay();//子类中调用父类中被隐藏的方法(因为子类重写了,所以就被隐藏了)
    	this.age = super.age;//super.调用父类中被隐藏的属性,创建子类对象时,调用了父类构造器已经给父类中age赋值了
    	this.name = "欧阳"; //已经继承了父类中属性和方法,也可以使用this.调用
    	System.out.println(age);//打印的是本类中的属性
    }
    
	public static void main(String[] args) {
		Son son = new Son();
        System.out.println(son);
        
        System.out.println();
        son.sonSay(); //调用子类中自己写的方法,也就是重写了父类的方法
        //this super 不能在static区域使用
	}
}

执行结果:

我是father带参空构造
我是father空构造
son带参构造
son空参构造
com.wmm.Son@15db9742
奥利给!
再接再厉
39

2、super()

构造器中相互调用,需在构造器代码中的第一行。
子类在new 对象,进行初始化(子类的构造器进行初始化 ),会自动调用父类的空构造(使用super() )。

特别说明;我们知道 ,类中会默认有一个空构造,所有子类在初始化时,会自动调用父类的空构造。
此时,在子类的构造器中,super(); 是可以省略的 ; 但当我们已经给父类创建了带参构造器,却没有创空构造器时,此时在初始化子类时,会报错,除非手动输入一个和我们在父类中定义相同参数类型的super()才可以,如super(int a);

下而详细介绍下在构造器中this()和super()相互调用执行顺序,这个可以啃啃

public class Father {
    int age;

    public Father(int age) {
        super(); //隐式存在
        this.age = age;
        System.out.println("我是father带参空构造");
    }

    public Father() {
        this(39);
        System.out.println("我是father空构造");
    }
}    
public class Son extends Father {
	
	int age;
    public Son(int age) { 
        System.out.println("son带参构造");
    }	    
    public Son() { 
    	this(3);
    	System.out.println("son空参构造");  
    }
    
	public static void main(String[] args) {
		Son son = new Son();
        System.out.println(son);		
	}

}

执行结果:

我是father带参空构造
我是father空构造
son带参构造
son空参构造
com.chabrain.Son@15db9742  

new Son()时,进入Son类的空参构造器,在空参构造器中,this(3)调用同类重载构造器,进入
带参构造器中,有隐式super(),调用上层父类空参构造器,构造器中有this(39),调用同类重载构造器,进入带参构造器中,有隐匿super() (Father类的父类为Object了,无打印信息),然后执行到最深入,再返回来,就开始是一个一个的打印信息了。

三、总结

this.和super.都能够调用属性和方法,但是 this. 调用的是本类中属性和方法,而 super. 调用的是父类中被隐藏的属性和方法。

this() 和 super() 都能够调用构造方法,但是某构造方法中 this([实参列表]) 调用的是同一个类中重载和该实参列表对应的构造方法,而 super([实参列表]) 调用的是父类中和该实参列表对应的构造方法。

我们要明白一个道理,在有继承关系时,创建子类对象,无论调用无参还有带参构造,都会调用父类的构造器,对父类对象初始化(但是在初始化父类对象前,先会执行子类中重载构造器中this()调用,执行后才会调用父类构造器,默认没有this()的构造器有隐式super(),当然也可以指定构带参构造器)。初始化父类对象,默认进入父类的空参构造器中(此时子类构造器中有个隐匿surper()),但如果调用子类构造器中第一行已经明确选择父类带参构造器,则进入父类带参构造器

还有一点也至关重要,当父类中有带参构造器,无空参构造,且子类中没有明确指出使用父类带参构造生成父类对象时,程序会默认使用super()空参构造生成父类对象,此时程序会报错。原因很简单:当一个类手动加入了带参构造器,系统将不会再为你自动生成空参构造。这时就需要我们为父类添加空参构造。

this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
 

参考链接:https://blog.csdn.net/ted_cs/article/details/82526056

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值