Java关键字super超详细解释

 更新时间:2023年11月17日 11:10:33   作者:Nianf  
在Java中super是一个关键字,用于访问父类中的属性、方法或构造函数,这篇文章主要给大家介绍了关于Java关键字super超详细解释的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言(废话文学)

又是看了一大堆文字介绍,非常系统和官方,理解要费半天劲,所以总结一下super它到底有啥用,还有代码演示也会放出来,这里使用的IDE为idea

前言(定义)

还是先官方一下

在java中,super表示超类(就是我们俗称的父类),当子类需要引用父类的字段时,我们就可以使用super.FieldName.
 

因此,本文就将从构造函数,公有成员函数,公有成员变量来分别演示super的作用,因为private私有成员是只允许自己使用的,所以这里也可以看出,super在继承关系中,对公有字段起作用。

super()之构造方法

如果父类(超类)没有默认的构造方法,子类就必须显式调用super(),并且必须使用父类中的某个构造方法的参数。

什么意思呢?
就是有一个父类Parent,子类Son,如果我们在Parent中定义了构造函数,那么在继承父类的子类中就必须书写父类的构造函数。那么此时就需要将super()写在子类构造方法中。
如果父类中没有定义构造方法,那么编译器会默认是public Parent(){}就是空的,此时在子类中不书写super也不会报错,因为编译器默认生成子类构造方法为空,super()就默认是隐藏的。
就是构造函数必须有super(),(开个玩笑:你说那我看到的有的咋没有,不是没有,只是只有聪明人能看见嘿嘿嘿。)如果子类中没有super(),那是因为编译器替你干了这个活,它隐藏了super()这个默认的无参构造方法,算是隐式调用。
注意显式二字。

来了来了,代码示例它来了

父类

public class Parent {
    //public Parent(){}//可以不写,编译器会默认是它,空的
    // 为了查看效果,我们把父类无参构造函数里加个输出
    public Parent(){
        System.out.println("This is Parent!");
    }
}

子类

public class Son extends Parent{
    public Son(){//此时不写super也不会报错,因为编译器默认是有super(),只不过隐藏了。
        System.out.println("This is son!");
    }
}

MyMain.java

public class MyMain {
    public static void main(String[] args){
        Son son = new Son();
    }
}

来,让我们看看效果,会发现父类构造方法也执行了。所以说super()意思就是调用父类的方法,往往我们通过传参的方式来达到我们所先要的结果

1

现在修改父类代码如下

public class Parent {
	public Parent(String name,int id){
	        System.out.println(name+"  "+id);
	    }
}

子类代码如下

public class Son extends Parent{
    public Son(String name,int id){
        System.out.println("This is son!");
    }
}

MyMain类代码如下

public class MyMain {
    public static void main(String[] args){
        String name ="Bob";
        int id=12;
        Son son = new Son(name,id);
    }
}

当当当,报错了,为啥,你没写super,因为默认隐藏super是super(),它没有传入任何参数,就导致子类在继承父类时,父类构造器就无法应用到子类中。

java: 无法将类 Parent中的构造器 Parent应用到给定类型;

1

修改子类代码如下,其它不变,发现可以运行了,因为传入了String参数和int参数,与父类一致,所以super()表示子类使用父类构造函数,(就是子类重载了父类函数,因为函数名和参数都必须相同),同时它也可以自己在构造函数中添加其它逻辑:

public class Son extends Parent{
    public Son(String name,int id){
        super(name, id);
        System.out.println("This is son!");
    }
}

1

super()之成员函数

对于可继承的成员函数,如果子类在重写父类的方法同时想要调用(实现)与父类相同的方法,那么就用super.func(obj,obj,…)。与构造函数不同的是,super.func()可以不用放在函数一开始的位置,而构造方法的super()必须放在函数体中最前面的位置。

来了来了,代码示例它来了

父类

public class Parent {
    private String name="Pang pang";
    private int id=12;
    private String selfIntro="This is a fat parent";
    public Parent(){}
    public void getName() {
        System.out.println(name);
    }
    public void getId(){
        System.out.println(id);
    }
    public void getSelfIntro() {
        System.out.println(selfIntro);
    }
}

子类

public class Son extends Parent{
    private static String sonIntro="This is Feifei's child";
    public Son(){System.out.println("This is Son:");}

    @Override
    public void getSelfIntro() {
        System.out.println(sonIntro);
        System.out.println("I want to see my parents' introduction: ");
        super.getSelfIntro();//可写可不写,只是看子类想不想调用它,它可以放在任何想调用的位置,返回的是父类的介绍
        //如果子类想调用却不写super的话就会报错
    }
}

主类

public class MyMain {
    public static void main(String[] args){
        //从子类读取信息
        Son son = new Son();
        son.getSelfIntro();
    }
}

结果展示

1

看到这,你一定想问,那要是一个有参数的成员函数咋个整呢,是啊,咋个整呢。其实你会发现,需要传参的一般情况下不会再调用super,因为子类优先原则会覆盖掉父类的数据,比如下面来演示一下。当然有的参数不影响的情况下,想要调用父类的含参成员函数还是可以调用super的

父类

public class Parent {
    private String name;
    private int id;
    public Parent(){}

    public void setInfo(String name,int id){
        this.name=name;
        this.id=id;
    }
    public void getInfo(){
        System.out.println(name+"  "+id);
    }
}

子类

public class Son extends Parent{
    private String name;
    private int id;
    public Son(){}
    @Override
    public void setInfo(String name,int id){
        super.setInfo(name,id);//将值传递给父类
        this.name=name;
        this.id=id;
    }
    @Override
    public void getInfo(){//打印信息
        System.out.println("This is parents' information:");
        super.getInfo();
        System.out.println("This is son's information: ");
        System.out.println(name+"  "+id);
    }
}

主类

public class MyMain {
    public static void main(String[] args){
        //由于子类优先原则,会将所有的值由子类传递给父类,顺便演示一下子类优先原则
        //设置父类信息
        Parent parent=new Parent();
        String pName="Pang pang";
        int pId = 11;
        parent.setInfo(pName,pId);
        System.out.println("This is first parent:");
        parent.getInfo();//打印出来看看,此时还是很正常的父类的值
        //设置子类信息,会发现父类信息失效了
        Son son = new Son();
        String sName = "Fei fei";
        int sId = 15;
        son.setInfo(sName,sId);
        son.getInfo();
    }
}

1

super()之成员变量

通过super.变量名就可以在子类中访问父类的成员变量,但是只有protected和public的成员变量可以被访问,而private的变量子类是访问不到的。

父类

public class Parent {
    private String inf1 = "Parent: stupid!";
    protected String inf2 = "Parent: Kids!";
    public String inf3 = "Parent: eat!";

}

子类

public class Son extends Parent{
    private String inf1;
    protected String inf2;
    public String inf3;
    public Son(){}
    public void setInfo(String inf1,String inf2,String inf3){
        this.inf1=inf1;
        this.inf2=inf2;
        this.inf3=inf3;
    }
    public void getInfo(){//打印信息
        System.out.println("This is son's information: ");
        System.out.println(inf1);
        System.out.println(inf2);
        System.out.println(inf3);
        System.out.println("This is parents' information:");
        //System.out.println(super.inf1);
        System.out.println(super.inf2);
        System.out.println(super.inf3);
    }
}

主类

public class MyMain {
    public static void main(String[] args){
        //设置子类信息
        Son son = new Son();
        String ss1 = "Son: mom!";
        String ss2 = "SOn: sorry!";
        String ss3 = "Son: play!";
        son.setInfo(ss1,ss2,ss3);
        son.getInfo();

    }
}

运行结果

1

如果调用了private变量时会报错的,如下图

1

总结

到此这篇关于Java关键字super超详细解释的文章就介绍到这了,更多相关Java关键字super内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis saveBatch 性能调优的实现

    MyBatis saveBatch 性能调优的实现

    本文主要介绍了MyBatis saveBatch 性能调优的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java开发必会的Linux命令

    Java开发必会的Linux命令

    这篇文章主要介绍了Java开发必会的Linux命令,帮助大家更好地进行java开发,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • Java实现合并多个PDF的示例代码

    Java实现合并多个PDF的示例代码

    这篇文章主要介绍了通过Java实现合并多个PDF,并将合并后的新PDF存储到文件夹下,文中的示例代码简洁易懂,感兴趣的可以跟随小编一起试一试
    2022-01-01
  • Java实现日志文件监听并读取相关数据的方法实践

    Java实现日志文件监听并读取相关数据的方法实践

    本文主要介绍了Java实现日志文件监听并读取相关数据的方法实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Spring Boot异步输出Logback日志方法详解

    Spring Boot异步输出Logback日志方法详解

    这篇文章主要给大家介绍了关于Spring Boot异步输出Logback日志的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • JDBC连接mysql乱码异常问题处理总结

    JDBC连接mysql乱码异常问题处理总结

    这篇文章主要介绍了JDBC连接mysql乱码异常问题处理的办法和思路,有需要的朋友参考学习下。
    2017-12-12
  • spring中通过ApplicationContext getBean获取注入对象的方法实例

    spring中通过ApplicationContext getBean获取注入对象的方法实例

    今天小编就为大家分享一篇关于spring中通过ApplicationContext getBean获取注入对象的方法实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • MyBatis查询缓存实例详解

    MyBatis查询缓存实例详解

    查询缓存的使用,主要是为了提高查询访问速度。这篇文章主要介绍了MyBatis查询缓存,需要的朋友可以参考下
    2017-06-06
  • Java中security与shiro的区别详解

    Java中security与shiro的区别详解

    这篇文章主要介绍了Java中security与shiro的区别详解,Spring Security在架构上将认证与授权分离,并提供了扩展点,它是一个轻量级的安全框架,它确保基于Spring的应用程序提供身份验证和授权支持,需要的朋友可以参考下
    2023-08-08
  • Java开启新线程并传参方法代码实现

    Java开启新线程并传参方法代码实现

    这篇文章主要介绍了Java开启新线程并传参方法代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04

最新评论