• 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()这个默认的无参构造方法,算是隐式调用。
    注意显式二字。
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    父类

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

    子类

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

    MyMain.java

    public class MyMain {
        public static void main(String[] args){
            Son son = new Son();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    public class Parent {
    	public Parent(String name,int id){
    	        System.out.println(name+"  "+id);
    	    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子类代码如下

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

    MyMain类代码如下

    public class MyMain {
        public static void main(String[] args){
            String name ="Bob";
            int id=12;
            Son son = new Son(name,id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    当当当,报错了,为啥,你没写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
    • 2
    • 3
    • 4
    • 5
    • 6

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    子类

    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的话就会报错
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    主类

    public class MyMain {
        public static void main(String[] args){
            //从子类读取信息
            Son son = new Son();
            son.getSelfIntro();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果展示
    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    子类

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    主类

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1

    super()之成员变量

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

    父类

    public class Parent {
        private String inf1 = "Parent: stupid!";
        protected String inf2 = "Parent: Kids!";
        public String inf3 = "Parent: eat!";
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    子类

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    主类

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    结束语

    总结在前言,到此super解析完成,若有疑问或者任何问题欢迎指出。

  • 相关阅读:
    【MyBatis源码分析】二、MyBatis回顾
    if消除术之 Map + Function
    Flask 学习-25.passlib 对密码加密与验证
    Windows11 Beta通道更新22622.575后无法使用Win+Q搜索功能
    深度学习十年感悟,从入门到放弃
    Python基于django的图书商城管理系统毕业设计源码110938
    「笔记」OfferCoder:剑指Offer刷题笔记
    标号变迁系统(Labelled Transition System)
    基于CppHttpLib的Httpserver
    元年专利解析|元数据管理系统和使用其对模型对象进行建模的方法
  • 原文地址:https://blog.csdn.net/qq_43738932/article/details/126637221