• Java 构造函数里的一些坑- super() 和 this()


    super() 和 this()

    这个很好理解, super() 就是在子类的构造函数里调用父类的构造函数
    this() 就是调用同类的另1个不同参数类型的构造函数.

    坑1 super() 和 this() 都只能用在构造函数中, 且必须是方法体第一行

    大家都知道, 其实这不算坑



    坑2 某些情况下, 构造方法不会被自动继承, 如果需要必须重写

    例如, 父类:

    @Slf4j
    public class ParentC1 {
    
        private int id;
        private String name;
    
        public ParentC1(){
            this.id = 1;
            this.name = "name";
            log.info("ParentC1()..");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    子类:

    @Slf4j
    public class ChildC1 extends ParentC1 {
    	 private int age;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这时子类是自动继承父类的无参函数的, 可以被实例化…

    但是 如果加上另1个参数类型的构造函数给子类

    @Slf4j
    public class ChildC1 extends ParentC1 {
    
        private int age;
        public ChildC1(int id, String name) {
            this.age = 1;
            log.info("ChildC1(id, name)..");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这时就不能通过无参构造函数实例化子类了, 因为java发现子类已有1个构造函数, 不会自动从父类继承

    在这里插入图片描述



    坑3 子类总会隐含地调用父类构造函数(super())

    注意, 这里两个关键字, 隐含和调用
    隐含意思是隐患了super() 声明, 调用是指的调用而不是继承。

    例子1:

    例如, 父类:

    @Slf4j
    public class ParentC1 {
    
        private int id;
        private String name;
    
        public ParentC1(){
            this.id = 1;
            this.name = "name";
            log.info("ParentC1()..");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    子类:

    @Slf4j
    public class ChildC1 extends ParentC1 {
    
        private int age;
        public ChildC1() {
           log.info("ChildC1()..");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这是调用子类无参构造和函数时,会调用父类无参构造方法, 无论有无声明super()
    在这里插入图片描述

    例子2:

    例如, 父类:

    @Slf4j
    public class ParentC1 {
    
        private int id;
        private String name;
        
        public ParentC1(){
            this.id = 1;
            this.name = "name";
            log.info("ParentC1()..");
        }
        
    	public ParentC1(int id, String name) {
            this.id = id;
            this.name = name;
            log.info("ParentC1(id, name)..");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    子类:

    @Slf4j
    public class ChildC1 extends ParentC1 {
    	 private int age;
    
        public ChildC1(){
            log.info("ChildC1()..");
        }
    
        public ChildC1(int id, String name) {
            super(id,name);
            this.age = 1;
            log.info("ChildC1(id, name)..");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    父类和都增加了(int id, String name) 这个双参构造 函数
    在子类的双参构造函数里显示调用父类的双参构造函数。

    这时, 调用子类双参构造函数时, 父类的双参构造函数会被调用, 顺理成章,这例子主要用于下面的例子对比。
    在这里插入图片描述

    例子3:

    例如, 父类:

    @Slf4j
    public class ParentC1 {
    
        private int id;
        private String name;
        
        public ParentC1(){
            this.id = 1;
            this.name = "name";
            log.info("ParentC1()..");
        }
        
    	public ParentC1(int id, String name) {
            this.id = id;
            this.name = name;
            log.info("ParentC1(id, name)..");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    子类:

    @Slf4j
    public class ChildC1 extends ParentC1 {
    	 private int age;
    
        public ChildC1(){
            log.info("ChildC1()..");
        }
    
        public ChildC1(int id, String name) {
            //super(id,name);
            this.age = 1;
            log.info("ChildC1(id, name)..");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这个例子3 对比例子2 只是隐藏了子类双参构造函数里的 super(id, name)
    重点来了, 这是调用子类双参构造函数,仍然会尝试调用父类的构造函数, 但是会默认调用父类的无参构造函数。

    在这里插入图片描述

    例子4:

    例如, 父类:

    @Slf4j
    public class ParentC1 {
    
        private int id;
        private String name;
          
    	public ParentC1(int id, String name) {
            this.id = id;
            this.name = name;
            log.info("ParentC1(id, name)..");
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    子类:

    @Slf4j
    public class ChildC1 extends ParentC1 {
    	 private int age;
    
        public ChildC1(){
            log.info("ChildC1()..");
        }
    
        public ChildC1(int id, String name) {
            //super(id,name);
            this.age = 1;
            log.info("ChildC1(id, name)..");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    例子4 相对于例子3 删除了父类的无参构造函数, how is it then?
    这是编译失败, 同时会被IDE科普教育
    子类找不到可以默认调用的父类无参函数,

    而子类双参构造 函数是不会默认调用父类的双参构造函数的, 即使参数类型完全一样。
    在这里插入图片描述

  • 相关阅读:
    Spring Bean 作用域与生命周期
    openstack——4、开启虚拟机
    华曙高科冲刺科创板:拟募资6.6亿 实控人许小曙父子均为美国籍
    掌握排序算法面试法宝,不会代码也能薪资过万
    Docker网络管理
    最新720全景云系统/可生成小程序+带PC端+安装教程/价值800元的720云全景系统源码
    el-date-picker日期列表样式更换为完全不同的样式保证弹出日期弹窗的功能不变
    基于yolov8的车牌检测训练全流程
    python 库笔记:logging 之模块级别函数
    中国智慧建造调研分析及投融资前景研究报告2022-2028年新版
  • 原文地址:https://blog.csdn.net/nvd11/article/details/126926028