派生的构造函数

时间:2009-11-04 10:18:46

标签: java constructor derived

在以下代码中:

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

3 个答案:

答案 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()。如果没有,它会增加一个。

希望这有帮助!