问题刨析——为什么构造函数中,this()与super()不能同时存在?

思路:首先要明白this()与super()各自的功能,再谈两者同时出现在一个构造函数中时,为什么会报错。

一. this()

  在形参列表较少的构造方法中被调用,跟函数一样,括号中可以写形参列表,用于调用同一实例下的其他构造器,由于不同构造器中存在相同代码,为了提高复用性,可以在参数较少的构造器中,使用this(部分形参列表)的方式,调用参数较多的构造器。如下:

 

 1 class Student{
 2         String name;
 3         int age;
 4         int id;
 5         public Student(String name, int age, int id) {
 6             this.name = name;
 7             this.age = age;
 8             this.id = id;
 9             System.out.println("构造器3已调用");
10         }
11         public Student(String name, int age) {
12             this(name,age,0);
13             System.out.println("构造器2已调用");
14         }
15 
16         public Student(String name) {
17             this(name,0);//参数不足,就使用参数默认值补全
18             System.out.println("构造器1已调用");
19         }
20         @Override
21         public String toString() {
22             return "Student [ id=" + id + ", name=" + name + ", age=" + age +"]";
23         }
24     }
25 测试结果1:
26     public static void main(String[] args) {
27         Student s=new Student("小明明");
28         System.out.println(s);
29     }   
30 
31     构造器3已调用
32     构造器2已调用
33     构造器1已调用
34     Student [ id=0, name=小明明, age=0]
35 
36 测试结果2:
37     public static void main(String[] args) {
38         Student s=new Student("小明明",20);
39         System.out.println(s);
40     }
41     构造器3已调用
42     构造器2已调用
43     Student [ id=0, name=小明明, age=20]

this()总结:以参数最多的构造器为代表,在参数较少的构造器中调用,实现代码的复用。

二. super()

  指代距离最近的父类构造函数,但在子类的构造器中,如果没有声明,会默认调用父类无参构造器。

需要注意的是,调用super()时,形参列表中不能有超过this()中的类型。

其余用法与tihs()同理,此处不再赘述。

三. 为什么报错

  首先是不安全,因为在构造函数中,会在第一行声明super(),此时super()默认先调用父类的无参构造,或者super()调用有参构造,然后再完成子类特有属性的初始化。而在子类的构造函数中this()调用的是子类中的其他构造函数,其他构造函数中必然会有默认调用父类无参构造方法,或直接调用有参构造方法的构造函数,此时,同一个子类构造器中声明了两次父类构造函数,即父类初始化了两次,造成不安全的问题。

  再者是失去了语句的意义,如果同时在子类构造方法中调用了两次同样的构造函数,编译器不通过。

 

posted @ 2020-06-16 09:39  早睡健康长寿  阅读(713)  评论(0)    收藏  举报