Java Don';不在子类的构造函数中创建supperclass实例,但完全合法
我在scjp指南中读到如下内容 事实上,如果不调用 对象的实际类类型的构造函数,以及 每个超类的构造函数 比如说Java Don';不在子类的构造函数中创建supperclass实例,但完全合法,java,oop,constructor,constructor-overloading,Java,Oop,Constructor,Constructor Overloading,我在scjp指南中读到如下内容 事实上,如果不调用 对象的实际类类型的构造函数,以及 每个超类的构造函数 比如说 public class Person{ } public class Employee extends Person{ public Employee(){ } } 我不创建Person实例,但它是合法的 请给我解释一下,谢谢你的帮助。它们的真正含义是 当您创建一个子类对象时,即调用其构造函数,然后调用超类构造函数 这是因为对于默认的无参数构造函数,有一个对超类构造函
public class Person{
}
public class Employee extends Person{
public Employee(){
}
}
我不创建Person实例,但它是合法的
请给我解释一下,谢谢你的帮助。它们的真正含义是
- 当您创建一个子类对象时,即调用其构造函数,然后调用超类构造函数
- 这是因为对于默认的无参数构造函数,有一个对超类构造函数的默认
调用李>super()
- 这类似于类层次结构,直到
类李>对象
public class Super {
public Super(int num){
}
}
public class Sub extends Super {
}
这里,类Sub
将不会编译,因为默认构造函数的隐式超级构造函数super()未定义,因为它无法在超类中找到无参数构造函数,因为默认无参数构造函数
即编译器提供的将隐式调用super()
- 仅当未定义其他构造函数时,编译器才提供默认的无参数构造函数
- 由于我们已经明确定义了
Super(intnum)
,我们将不得不明确地创建如下的无参数构造函数
public Super(){
}
隐式调用了超类的空构造函数。其原因是构造函数链接:
默认情况下,any构造函数中的第一条语句是super();(这是对超级类默认构造函数的调用)
我不创建Person实例,但它是合法的:
这是因为Person类中有一个默认构造函数。所以Employee类构造函数实际上可以调用超级类构造函数Person()
底线是,您在其中声明构造函数的当前类,到基类的所有构造函数都应该可以通过super()访问。如果没有,则必须使用适当的参数通过super显式调用来显式地使其可访问。首先,不必创建父实例(parent
)来实例化子类(Employee
)。你一定理解错了
调用父类的构造函数并不意味着创建一个新的父实例对象(您没有使用new
调用它,因此不会创建新实例)。您正在创建一个子实例,为此,由于继承的原因,需要首先调用父实例的构造函数。例如,假设父类具有必须在构造函数中初始化的private
字段(例如private final
字段)。此字段不能从子类访问,但可以从父类构造函数初始化。您需要在子实例中初始化此字段,唯一的方法是调用super()
在这种情况下,Person
有一个默认的构造函数,默认情况下被调用,无需显式调用它
但如果Person
没有默认构造函数,则需要显式调用它。例如:
public class Person{
private final String name;
public Person(final String name) {
this.name = name;
}
}
public class Employee extends Person {
public Employee() {
}
}
public class Employee extends Person {
public Employee(final String name) {
super(name);
}
}
这将无法编译。您需要修改Employee
,以便它显式调用Person
构造函数。例如:
public class Person{
private final String name;
public Person(final String name) {
this.name = name;
}
}
public class Employee extends Person {
public Employee() {
}
}
public class Employee extends Person {
public Employee(final String name) {
super(name);
}
}
无论何时实例化子类,它都会首先调用超类的构造函数
您可以在此处找到更多关于此的信息:
Person.java
public class Person {
public Person() {
System.out.println("Super class constructor called");
}
}
public class Employee extends Person {
public Employee() {
System.out.println("Sub class constructor called");
}
}
Employee.java
public class Person {
public Person() {
System.out.println("Super class constructor called");
}
}
public class Employee extends Person {
public Employee() {
System.out.println("Sub class constructor called");
}
}
如果您随后实例化您的员工:
Employee e = new Employee();
输出:
Employee e = new Employee();
调用的超类构造函数
调用子类构造函数
您遇到了java的一个奇怪之处
如果未定义任何构造函数、默认值或“无参数”,则构造函数是隐式定义的。这就像是看不见的代码
如果您定义任何构造函数、参数或无参数,则隐式默认构造函数将消失
为了进一步加深谜团,任何子类构造函数的第一行必须是调用超类的构造函数。如果没有显式调用,则会隐式调用no args构造函数。没有收到您的问题吗?你能解释更多吗?我的意思是,我没有在员工的构造函数中创建Person实例,但它是合法的。+1因为这是唯一的答案,不是完全关注构造函数链接,而是解释Person和员工之间的关系。无论何时创建Employee对象,它都是Person对象。@是的,没有其他答案可以解释OP问题:“我不创建Person实例,但它是合法的。”但它们得到了投票并被接受。像往常一样奇怪:实际上没有回答这个问题:“我没有创建Person实例,但它是合法的。”