0

在以下代码中:

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 类型的实例时,基类的构造函数也会被执行?

4

3 回答 3

5

因为您的子类扩展了基类——它是基类的一个实例,并且具有所有相同的字段和变量等。因此,基类也必须被实例化。

举一个具体的例子,想象你的基类有以下内容:

public class Base
{
    final private int id;

    public Base()
    {
        this(-1);
    } 

    public Base(int id)
    {
        this.id = id;
    }

    public getId()
    {
        return id;
    }
}

在构造类时,保证会实例化最终变量。您的子类将有一个id字段(即使它无法使用子方法直接访问它),并且由于该字段是私有的,因此您无法使用子构造函数对其进行实例化 - 因此必须调用基类构造函数。

请记住,这不仅仅是最终变量的问题,也不是您可能使用的任何特定功能所独有的 - 因为您的子类一个基类,它需要被正确地实例化为一个。

于 2009-11-04T10:28:36.470 回答
2

因为那是应该发生的:-)

您的派生类使用基类作为基础。在 OO 中,它是一个基类。该基类还需要初始化自身,因此必须调用其构造函数。

从您的示例中并不明显,但是如果您为基类提供一些(受保护的)成员,它会更有意义。在基本构造函数中初始化它们,因此在构造时从派生类查看时它们将具有预期值。

见下文。该字段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);
    }
}
于 2009-11-04T10:22:58.147 回答
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;
    }
 }

车辆是父类

 class Car extends Vehicle {
  public Car(){
    #Compiler add the super() constructor by default
        System.out.println("Car class constructor");
    }
}

汽车是子类

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 类是否有任何父类,只要它检查 Car 类扩展了父类 Vehicle ,它就会检查用户是否有在继承树中提供了 super()。如果没有,它会增加一个。

希望这可以帮助 !

于 2009-11-04T11:50:41.470 回答