Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Don';不在子类的构造函数中创建supperclass实例,但完全合法_Java_Oop_Constructor_Constructor Overloading - Fatal编程技术网

Java Don';不在子类的构造函数中创建supperclass实例,但完全合法

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实例,但它是合法的 请给我解释一下,谢谢你的帮助。它们的真正含义是 当您创建一个子类对象时,即调用其构造函数,然后调用超类构造函数 这是因为对于默认的无参数构造函数,有一个对超类构造函

我在scjp指南中读到如下内容

事实上,如果不调用 对象的实际类类型的构造函数,以及 每个超类的构造函数

比如说

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实例,但它是合法的。”