学习笔记:this和super

本文详细讲解了Java中this关键字的作用,如何在实例方法和构造方法中引用自身,并介绍了super的使用场景,包括调用父类构造方法和访问父类属性与方法。特别强调了this()与super()在构造方法中的顺序和限制。
摘要由CSDN通过智能技术生成

学习内容:this和super

1.1 this

1.this是Java的一个关键字,是一个引用,保存当前对象的内存地址指向自身。

例:

// An highlighted block
public class thisTest {
    public static void main(String[] args) {
            Customer c1=new Customer("张三");
            Customer c2=new Customer("李四");
            c1.shopping();
            c2.shopping();
    }
}
class Customer{
    String name;

    public Customer(){}

    public Customer(String name){
        this.name=name;//这里的"this"指的是成员变量"name"
    }

    public void shopping(){
        System.out.println(name+"正在购物!");//这个name前面有一个“this.”被省略了
    }
}

这里的"this.name"指的是成员变量name,因为有参构造方法里面的局部变量名和Customer类的成员变量名一样也是name,为了方便区分就加上"this."。
如果局部变量名和成员变量名不一样,这里是"this."是可以省略的。反正就不能省略。

public Customer(String name){
        this.name=name;//这里的"this"指的是成员变量"name"
    }

这里创建了两个对象c1和c2,再分别用这两个对象去调用shopping()方法

	Customer c1=new Customer("张三");
 	Customer c2=new Customer("李四");
    c1.shopping();
    c2.shopping();

在这里插入图片描述
shopping()方法输出的name前面是有一个"this.“的,只不过被省略了。当对象c1调用shopping()方法时,这里的"this"指的是c1对象的地址,也就是c1;当对象c2调用shopping()方法时,这里的"this"指的是c2对象的地址,也就是c2。无论是哪个对象去调用这个shopping()方法,“this"表示的都是调用这个方法的对象。
如果将这里的"this.“改为"c1.”(或者是"c2.”),那么当c2对象调用shopping()方法时,输出的是"c1.name”,就是c1对象的name了。

this在内存图中的存储结构是怎样的呢?(以上述代码为例)
this的内存图

2.2 this()

通过当前的构造方法去调用一个本类的构造方法,可以使用this(),格式如下

this(参数列表);

通过构造方法1去调用构造方法2,能做到代码复用;但前提是构造方法1和构造方法2必须在同一个类当中。

例:

public class thisTest01 {
    public static void main(String[] args) {
        Date d1=new Date();
        d1.show();
        Date d2=new Date(2001,9,25);
        d2.show();

    }
}

class Date{
    private int year;
    private int month;
    private int day;

    public Date() {
        /*this.year=2001;
        this.month = 12;
        this.day = 5;*/
        this(2001,12,5);//这一行代码等同于上面三行代码
    }

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void show(){
        System.out.println(year+"年"+month+"月"+day+"日");
    }
}

这里用无参构造方法和有参构造方法分别new了一个对象。在new对象的时候对成员变量初始化,因为d1是用无参构造方法创建的对象,所以成员变量会赋默认值(这里是int型,所以默认值是0),而d2创建对象的时候给了一个值,所以输出的就会是给的那个值。

Date d1=new Date();
d1.show();
Date d2=new Date(2001,9,25);
d2.show();
 public Date() {
    }

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

运行结果:
运行结果
若是在无参构造里面直接给成员变量赋值,创建对象的时候就不会给成员变量赋默认值,就相对与你在无参构造里面赋值就是给成员变量的默认值。

Date d1=new Date();
d1.show();
public Date() {
	this.year=2001;
	this.month = 12;
	this.day = 5;
}

在这里插入图片描述

如果你将上述代码换成this(2001,12,5);就是在无参构造方法里面调用了有参方法,实现了代码的复用。

public Date() {
        this(2001,12,5);
}

在这里插入图片描述
注意:this()只能出现在代码的第一行!!一个构造方法里面也只能有一个this()

2.1 super

super的使用:

super.属性名		 【访问父类的属性】
super.方法名()		 【访问父类的方法】
super()					 【调用父类的构造方法】

当子类中有和父类同名的属性同样的方法时,可以用super.来访问父类的属性或方法
例:

public class superTest {
    public static void main(String[] args) {
            Vip v=new Vip("张三");
            v.shopping();
    }
}
class Customer1{
    String name;
    public Customer1() {}
    public Customer1(String name) {
        this.name = name;
    }
    public void shopping(){
        System.out.println("这是父类的方法");
    }
}

class Vip extends Customer1{
    String name;
    public Vip(String name) {
        super(name);//调用父类的成员变量name
        //this.name=null;  会给Vip里面的成员变量赋默认值null
    }
    public void shopping(){
        super.shopping();//调用父类的shopping()方法
        System.out.println(this.name+"正在购物!");
        System.out.println(super.name+"正在购物!");
        System.out.println(name+"正在购物!");//name前面应该有一个"this."被省略了
    }
}

在这里插入图片描述

2.2 super()

super()可以在子类的构造方法中调用父类的构造方法。格式如下

super(参数列表);

例:

public class superTest {
    public static void main(String[] args) {
        new B();
    }
}
class A{
    public A() {
        System.out.println("A的无参构造!");
    }
}

class B extends A{
    public B() {
        System.out.println("B的无参构造");
    }
}

在这里插入图片描述
为什么上述代码明明是调用B的构造方法去创建对象,怎么A的构造方法也运行了呢?
其实子类的构造方法中,第一行默认会有super();的代码,只是我们看不到,但是当我们手动写了这行代码之后,默认的super();就没有了。

new B();
public B() {
        super();
        System.out.println("B的无参构造");
    }

在这里插入图片描述
注意:跟this()一样,super()也只能出现在方法里的第一行

那么如果一个构造方法里面同时有this()和super(),那程序到底运行的是谁呢?
我们把上面的例子改一下:

class B extends A{
    public B() {
        this(10);
        super();
        System.out.println("B的无参构造");
    }
    public B(int a){
        System.out.println("B的有参构造");
    }
}

运行后发现报错,说“super必须是构造器中的第一个语句”。
在这里插入图片描述
我们将this()和super()交换位置后,发现无论是this()还是super()都要放在第一行。

class B extends A{
    public B() {
    	super();
        this(10);
        System.out.println("B的无参构造");
    }
    public B(int a){
        System.out.println("B的有参构造");
    }
}

在这里插入图片描述
所以在一个构造方法中,有了this()就不能有super(),有了super()就不能有this()。

那如果构造方法里面有了this(),那到底是运行this()还是运行super()呢?

public class superTest {
    public static void main(String[] args) {
        new B();
    }
}
class A{
    public A() {
        System.out.println("A的无参构造!");
    }
}

class B extends A{
    public B() {
        this(10);
        System.out.println("B的无参构造");
    }
    public B(int a){
        //super();
        System.out.println("B的有参构造");
    }
}

在这里插入图片描述
这里是new B();调用B的无参构造----->运行this(10);去调用B的有参构造----->运行默认的super();,去调用A的无参构造----->输出“A的无参构造!”(A的无参构造运行结束)----->输出“B的有参构造”(B的有参构造运行结束)----->输出“B的无参构造”(程序运行结束)

所以,当构造方法里面有了this()之后,默认的super()就不存在了。

学习总结

1. this

  1. this是一个关键字,是一个引用,保存内存地址指向自身。
  2. this可以使用在实例方法中,也可以使用在构造方法中。
  3. this出现在实例方法中其实代表的是当前对象。
  4. this不能使用在静态方法中。
  5. this.大部分情况下可以省略,但是用来区分局部变量和实例变量(成员变量)的时候不能省略。
  6. this()这种语法只能出现在构造方法的第一行,表示当前构造方法调用本类其他的构造方法,目的是代码复用。

2. super

  1. super能出现在实例方法和构造方法中。
  2. super的语法是super.super()
  3. super不能使用在静态方法中。
  4. super.大部分情况下是可以省略的。
  5. 当父类和子类中有同名属性,或者是有同样的方法,想在子类中访问父类的属性或者是方法,super.不能省略。
  6. super()只能出现在构造方法的第一行,通过当前的构造方法去调用”父类“中的构造方法,目的是:创建子类对象的时候,先初始化父类特征(属性)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值