51

I have a question about default constructors and inheritance in Java.

Generally, if you write a class and do not include any constructor, Java provides automatically for you a default constructor (one without parameters), which initializes all instance variables of the class (if there are any) with some default values (0, null, or false). If you write a constructor, however, with some parameters, and you don't write any default constructor, then Java does not provide a default constructor. My question is: what is the case with classes, which inherit from other classes - if I write a constructor with some parameters in them, but don't include a default constructor, do they inherit the default constructor of the super class?

4

11 回答 11

63
  1. 如果不创建构造函数,则会自动创建默认的空构造函数

  2. 如果任何构造函数没有显式调用 super 或 this 构造函数作为其第一条语句,则会自动添加对 super() 的调用

总是。

于 2009-02-09T03:38:14.807 回答
52

Constructors are not inherited.

Also, the initialization of fields is done by the virtual machine, not the default constructor. The default constructor just invokes the default constructor of the superclass, and the default constructor of Object is empty. The good point of this design is that there is no way to ever access uninitialized fields.

于 2009-02-08T11:17:28.693 回答
11

Unless you use super(...) a constructor calls the empty constructor of its parent. Note: It does this on all you classes, even the ones which extend Object.

This is not inheriting, the subclasses don't get the same constructors with the same arguments. However, you can add constructors which call one of the constructors of the super class.

于 2009-02-08T11:18:28.770 回答
6

基本规则是对构造函数的调用(或调用)应该是 JVM 需要执行的第一条语句,

所以当你有一个只有参数化构造函数而没有默认构造函数的超类,并且基类没有显式调用超类的参数化构造函数时,JVM 提供了 super(); call 抛出错误,因为超类没有默认构造函数,因此我们要么在超类中提供默认构造函数,要么在基类构造函数中显式调用超类的参数化构造函数。当我们进行显式调用时,JVM 不会费心放置 super(); 行。因为构造函数调用应该是方法的第一条语句,这不可能发生(因为我们显式调用)。

于 2012-11-29T18:49:47.957 回答
6

Java 语言规范的第 8.8.9 节详细解释了发生了什么:

如果类不包含构造函数声明,则隐式声明默认构造函数。顶级类、成员类或本地类的默认构造函数形式如下:

  • 默认构造函数具有与类相同的可访问性(第 6.6 节)。
  • 默认构造函数没有形式参数,除非在非私有内部成员类中,默认构造函数隐式声明一个形式参数,表示该类的直接封闭实例(§8.8.1、§15.9.2、§15.9.3 )。
  • 默认构造函数没有 throws 子句。
  • 如果声明的类是原始类 Object,则默认构造函数的主体为空。否则,默认构造函数只是调用不带参数的超类构造函数。

你可以看到这里没有继承:所有的一切都是带有隐式声明的默认构造函数的“编译器魔法”。规范还明确指出,只有当类根本没有构造函数时才会添加默认构造函数,这意味着您的问题的答案是“否”:一旦你给一个类一个构造函数,访问它的默认构造函数超类丢失了。

于 2015-02-13T15:37:28.607 回答
3

如果您提供构造函数,那么 Java 不会为您生成默认的空构造函数。所以你的派生类只能调用你的构造函数。

默认构造函数不会将您的私有变量初始化为默认值。证明是可以编写一个没有默认构造函数并将其私有成员初始化为默认值的类。这是一个例子:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}
于 2009-02-08T11:25:48.910 回答
2

拇指规则是子类应该从基类调用任何构造函数。因此,如果您没有默认的 const ,则从子类中调用现有的 const 。其他明智的做法是在基类中实现空 const 以避免编译问题

于 2011-06-23T11:22:01.277 回答
2

你的问题的答案很简单。隐式(不可见),任何构造函数中的第一条语句都是 'super();' 即对超类的无参数构造函数的调用,直到您将其显式更改为 'this();','this(int)','this(String)','super(int)','super(String )' 等 'this();' 是当前类的构造函数。

于 2017-03-23T09:31:11.230 回答
1

当我们不创建构造函数时,Java 会自动创建一个默认构造函数。但是当我们创建一个或多个带有参数的自定义构造函数时,Java 不会创建任何默认构造函数。如果我们创建一个或多个构造函数并且我们想要创建一个没有任何构造函数参数的对象,我们必须声明一个空的构造函数。

于 2011-01-26T09:46:27.013 回答
1

会有编译时错误...因为编译器会寻找默认的构造函数他的超类,如果它不存在......它是一个错误......并且程序将不会编译......

于 2017-08-30T18:37:07.610 回答
0

子类中的任何构造函数都会调用父类的无参数构造函数(或默认构造函数)。如果在父类中定义参数化构造函数,则必须使用 super 关键字显式调用父类构造函数,否则会产生编译错误。

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

上面的代码会给出编译错误:

prog.java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
    { 
    ^
  required: int,int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

发生上述错误是因为我们在父类中没有任何无参数构造函数/默认构造函数,也没有从子类调用参数化构造函数。

现在要解决这个问题,可以像这样调用参数化构造函数:

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        super(4, 5); // calling the parameterized constructor of parent class
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

输出

base
derived

或者

在父类中定义一个无参数构造函数,如下所示:

class Alpha 
{ 
    Alpha(){

    }
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

输出

derived 
于 2019-05-19T07:47:32.400 回答