java语言之super关键字详解

前言

你第一次遇到super关键字是什么时候呢?是不是使用IDEA或者eclipse快捷键生成类构造方法的时候出现在构造方法第一行的super()语句呢?在没有了解super关键字之前,相信你是很疑惑这行代码的作用的,没关系,本文带你全面详解super关键字,你就会知道这行代码有什么作用了(偷偷告诉你,实际上没有什么用,因为就算没有这一行代码JVM也会默认自动调用的)

一、super介绍

我们将super关键字与this关键字对比来介绍,因为两者有许多相似之处:
1.this只能出现在构造方法和实例方法(不带staric关键字的方法)之中,代表的是当前正在调用这个方法的对象
2.super也只能出现在构造方法和实例方法中,代表的是当前对象的父类型特征
注意:怎么去理解这个父类型特征呢?

 -  super关键字代表的就是“当前对象”的那部分父类型特征。
    比如: 我继承了我父亲的一部分特征 例如:眼睛、皮肤等
    那么super代表的就是“眼睛、皮肤等”,“眼睛、皮肤等”
    虽然是继承了父亲的,但这部分是长在我身上的。

二、super的语法

1.super的第一种语法是:“super(实参列表)”

这种语法的作用是:通过子类的构造方法去调用父类的构造方法,用来给当前子类的父类型特征初始化值。
注意:
1.这里的父类型特征指的是从父类继承过来的那部分属性或者行为
2.虽然调用了父类的构造方法,但是并没有在底层创建父类对象,只是给当前子类对象的父类型特征赋了值,实际上对象只有当前子类对象一个
3.super(实参列表)只能出现在子类构造方法的第一行
4.super(),括号里没有参数代表调用父类的无参数构造方法
5.因为需要模拟现实世界中有父母才会有儿子的这种关系,所以java有一条语法就是:
   子类的构造方法中第一行如果没有super(),也会默认有一个super(),表示通过子类构造方法去调用父类的无参构造方法,所以还必须保证父类的无参构造方法一定存在。
解释一下前言所提出的问题:   
我们知道java中有一个超级父类Object类,所有引用数据类型都是Object的子类,
包括自己自定义的类也会默认继承Object,所以当你使用快捷键生成一个类的构
造方法的时候,会默认在构造方法第一行出现super()代码,你将这一行代码删除
了也没事,因为会默认有这一行代码。   

举例代码如下:

public class Super {
    public static void main(String[] args) {
        Son son = new Son("张三",18,"华为");
        System.out.println(son.name);
        System.out.println(son.age);
        System.out.println(son.phoneName);
    }
}
/**
 * 父亲类:Parent
 * 说明:
 * 1.属性有:姓名、年龄、手机名
 * 2.方法有:构造方法
 */
class Parent{
    String name;//姓名
    int age;//年龄
    String phoneName;//手机名
    //无参构造
    public Parent() {}
    //有参构造
    public Parent(String name, int age, String phoneName) {
        this.name = name;
        this.age = age;
        this.phoneName = phoneName;
    }
}
/**
 * 儿子类:Son 继承父亲类
 * 说明:属性和方法都继承于父亲,也就是说,此时的Son所有属性和方法都是“父类型特征”
 */
class Son extends Parent{
    //子类Son的有参构造
    public Son(String name,int age,String phoneName) {
        //调用super(实参列表)调用父类的有参构造
        //给当前子类的父类型特征初始化值,其实也就是子类自己的属性
        //只不过是调用了父类的构造方法来初始化值
        super(name, age, phoneName);
    }
}

执行结果图示:
在这里插入图片描述

2.super的第二种语法是:“super.成员变量” 或者“super.成员方法”

这种语法的作用是:区分子类和父类中相同名字的成员变量或者相同名字的成员方法。

举例如下:假设有父亲类和儿子类,让儿子类去继承父亲类,儿子类和父亲类的属性和方法都相同,如何通过儿子类去访问继承自父亲的那部分特征呢,只有调用super关键字来区分,代码如下。

public class Super {
    public static void main(String[] args) {
       //创建一个儿子对象
       //注意:传入的参数赋值给了子类自身的属性,子类继承的父类型特征默认给了值: super("张三",50,"oppo");
       Son son = new Son("小小小张三",18,"华为手机");
       //此时调用son的访问父类型特征方法
       son.getParentData();
    }
}
/**
 * 父亲类:Parent
 * 说明:
 * 1.属性有:姓名、年龄、手机名
 * 2.方法有:构造方法、玩手机方法
 */
class Parent{
    String name;//姓名
    int age;//年龄
    String phoneName;//手机名
    //无参构造
    public Parent() {}
    //有参构造
    public Parent(String name, int age, String phoneName) {
        this.name = name;
        this.age = age;
        this.phoneName = phoneName;
    }
    //玩手机方法
    public void playPhone(){
        System.out.println("父亲在玩手机!");
    }
}
/**
 * 儿子类:Son 继承父亲类
 * 1.属性有:姓名、年龄、手机名
 * 2.方法有:构造方法、玩手机方法、访问父类型特征方法
 */
class Son extends Parent{
    String name;//姓名
    int age;//年龄
    String phoneName;//手机名
    //无参构造
    public Son() {}
    //有参构造
    public Son(String name, int age, String phoneName) {
        //通过子类给从父亲继承过来的父类型特征赋值
        super("张三",50,"oppo");
        //给子类自己的属性赋值
        //注意:子类中的name等属性和方法 与 父类中的name等属性和方法 是不同的
        this.name = name;
        this.age = age;
        this.phoneName = phoneName;
    }
    //设计一个访问父类型特征的方法
    public void getParentData(){
        //如果以下属性和方法都不加super关键字,那么就是调用子类自身的属性和方法
        System.out.println("父类型特征的name:" + super.name);
        System.out.println("父类型特征的age:" + super.age);
        System.out.println("父类型特征的phoneName:" + super.phoneName);
        //父类型特征的玩手机方法
        super.playPhone();
    }
    //玩手机方法
    public void playPhone() {
        System.out.println("儿子在玩手机!");
    }
}

程序执行结果为:
在这里插入图片描述

三、super内存图

还是以上边提出的父亲类和儿子类为例:
注意:子类中调用super()父类的构造方法,父类的构造方法还会继续调用它的父类的super()构造方法,但是实际上对象只创建了一个。所有调用的super()构造方法只是在子类对象在JVM堆区中的那一块空间中占用一小部分来给父类型特征初始化值。
在这里插入图片描述

四、super小结

1.super只能出现在构造方法和实例方法
2.super有两种语法
1)super.成员属性 或者 super.实例方法
作用:调用那部分父类型特征的属性或者方法(大多时候可以省略)
2)super(实参列表)
作用:通过子类构造方法去初始化从父类继承过来的那部分父类型特征
3.super是一个对象级的关键字,也就是说得有对象才能调用super,所以super不能出现在静态方法中(带有static关键字的方法)
4.当访问的子类属性与父类继承过来的属性或方法名字不一样时,super关键字可以省略不写
5.当访问的子类属性与父类继承过来的属性或方法名字一样时,你又想要访问父类型的这部分特征时,必须使用super关键字
6.super(实参列表)只能出现在构造方法第一行
7.如果构造方法第一行没有super(),默认第一行有super(),只是你看不到

  • 28
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ocean&21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值