在以下代码中:
import java.io.*;
public class MyClass1
{
MyClass1()
{
System.out.println("base class");
}
public void print()
{
System.out.println("base print");
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
System.out.println("child class");
}
public void print()
{
System.out.println("child print");
}
}
为什么当我创建ChildClass类型的实例时,基类的构造函数也会被执行?
答案 0 :(得分:5)
因为你的子类扩展了基类 - 它是基类的一个实例,并且具有所有相同的字段和变量等。因此,基类也必须被实例化。
对于一个具体示例,假设您的基类具有以下内容:
public class Base
{
final private int id;
public Base()
{
this(-1);
}
public Base(int id)
{
this.id = id;
}
public getId()
{
return id;
}
}
保证在构造类时实例化最终变量。您的子类将具有id
字段(即使它不能直接使用子方法访问它),并且由于此字段是私有的,因此无法使用子构造函数对其进行实例化 - 因此基类构造函数必须被召唤。
请记住,这不仅仅是最终变量的问题,也不是您可能使用的任何特定功能所特有的 - 因为您的子类 是基类,它需要是正确地实例化为一个。
答案 1 :(得分:2)
因为那是应该发生的事情: - )
派生类使用基类作为基础。在OO中说出是-a 基类。该基类也需要初始化,因此必须调用它的构造函数。
从您的示例中可以看出这一点并不明显,但如果您为基类提供一些(受保护的)成员,则会更有意义。在基础构造函数中初始化它们,因此在构造时从派生类中查看时它们将具有预期值。
见下文。字段value
在子类中可见。你期望什么作为初始值?
public class MyClass1
{
protected int value;
MyClass1()
{
System.out.println("base class");
this.value = 42;
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
// what would you expect 'value' to be here ?
System.out.println("child class " + value);
}
}
答案 2 :(得分:0)
因为默认情况下编译器在子类构造函数中添加了super()构造函数(如果未指定)。每个构造函数都应该在没有继承的情况下使用this()或者在存在继承时使用super()方法。为了说明这一点,我采用了这个例子。
public class Vehicle {
protected int wheels;
protected int lights;
Vehicle(){
System.out.println("Vehicle Class Constructor");
this.wheels=4;
this.lights=2;
}
}
Vehicle是父类
class Car extends Vehicle {
public Car(){
#Compiler add the super() constructor by default
System.out.println("Car class constructor");
}
}
Car是Child class
public class TestCar {
public static void main(String args[]){
Car c = new Car();
System.out.println("Wheels" + c.wheels);
System.out.println("Lights" + c.lights);
}
}
在上面的代码片段中当我在编译时编译TestCar.java文件时,编译器会查找Car构造函数,并在检查Car类是否扩展父类Vehicle时检查Car类是否有任何父类,它会检查用户是否在继承树中提供了super()。如果没有,它会增加一个。
希望这有帮助!