问题刨析——为什么构造函数中,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()调用的是子类中的其他构造函数,其他构造函数中必然会有默认调用父类无参构造方法,或直接调用有参构造方法的构造函数,此时,同一个子类构造器中声明了两次父类构造函数,即父类初始化了两次,造成不安全的问题。
再者是失去了语句的意义,如果同时在子类构造方法中调用了两次同样的构造函数,编译器不通过。

浙公网安备 33010602011771号