构造器中 this() & super()的使用, 多参数的情况下this() & super()又是怎么使用的
this()
和 super()
在 Java 构造器中的作用是调用其他构造器。它们都必须出现在构造器的第一行。具体来说:
this()
:this()
用于在一个构造器中调用同一类中的另一个构造器。它通常用于实现构造器重载,即在同一个类中根据不同的参数组合提供多个构造器。
例如:
public class Person {
private String name;
private int age;
// 默认构造器
public Person() {
this("Unknown", 0);
}
// 带有一个参数的构造器
public Person(String name) {
this(name, 0);
}
// 带有两个参数的构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
在这个例子中,我们使用 this()
在一个构造器中调用另一个构造器。默认构造器会调用带有两个参数的构造器,将姓名设置为 “Unknown”,年龄设置为 0。带有一个参数的构造器会调用带有两个参数的构造器,将年龄设置为 0。
super()
:super()
用于在子类构造器中调用父类的构造器。它用于确保子类在创建对象时能够正确地初始化其父类部分。
例如:
class Animal {
private String species;
public Animal(String species) {
this.species = species;
}
}
class Dog extends Animal {
private String name;
public Dog(String name) {
super("Dog"); // 调用父类的构造器
this.name = name;
}
}
在这个例子中,Dog
类继承了 Animal
类。Dog
类的构造器中使用 super()
调用 Animal
类的构造器,将物种设置为 “Dog”。
对于多参数的情况,this()
和 super()
可以接受不同数量和类型的参数,以匹配相应的构造器。例如:
public class Parent {
public Parent(int a, int b) {
// ...
}
}
public class Child extends Parent {
public Child() {
super(1, 2);
}
public Child(int a) {
this(a, 2);
}
public Child(int a, int b) {
super(a, b);
}
}
在这个例子中,Child
类继承了 Parent
类。Child
类有三个构造器,分别接受 0、1 和 2 个参数。每个构造器都会使用 this()
或 super()
调用另一个构造器,传递相应的参数。
为什么 this和super不能出现在同一个构造器中, 否则编译不通过
this()
和 super()
都用于调用其他构造器,但它们在构造器中的作用是不同的。this()
用于调用同一类中的另一个构造器,而 super()
用于调用父类的构造器。在 Java 中,这两个调用必须出现在构造器的第一行,因为在创建对象时,需要确保先初始化父类部分,然后再初始化子类部分。
在同一个构造器中同时使用 this()
和 super()
是不允许的,因为它们都必须出现在构造器的第一行。如果允许同时使用它们,那么它们中的一个将不在第一行,这违反了构造器调用的规则。此外,如果同时使用 this()
和 super()
,则意味着一个构造器同时调用了另一个构造器和父类的构造器,这在逻辑上是不一致的。
因此,Java 编译器会禁止在同一个构造器中同时使用 this()
和 super()
,以确保对象的正确初始化顺序并防止逻辑错误。