2009-02-08 106 views
50

我有一个关于Java中的默认构造函数和继承的问题。通常,如果您编写一个类并且不包含任何构造函数,Java会为您自动为您提供一个默认构造函数(一个不带参数),它初始化该类的所有实例变量(如果有的话),并带有一些默认值(0,null或false)。但是,如果你编写了一个构造函数,并且有一些参数,并且你不写任何默认的构造函数,那么Java就不会提供默认的构造函数。 我的问题是:什么是类的情况下,从其他类继承 - 如果我写一个构造函数的一些参数,但不包含默认的构造函数,他们是否继承了超类的默认构造函数?Java中的默认构造函数和继承

+1

是否需要后对假设“构造函数初始化类的所有实例变量(如果有的话)以及一些默认值(0,null或false)”的行进行编辑。“误导读者? – 2013-01-09 16:41:22

回答

51

构造函数不被继承。

此外,字段的初始化由虚拟机完成,而不是默认的构造函数。默认的构造函数只是调用超类的默认构造函数,而Object的默认构造函数是空的。这种设计的优点是没有办法访问未初始化的字段。

+1

是的,我刚刚明白这一点,下面的potyl指出了这一点。但是,如何(以及何时)初始化字段呢? (请参阅我对potyl的答案的评论)。 – user42155 2009-02-08 11:55:27

+0

当我创建对象时,Java是否会自动提供默认值?但是,再次,我们使用构造函数创建对象,对吧? – user42155 2009-02-08 11:57:25

+0

是的,花了一段时间来做研究w.r.t.初始化。 – starblue 2009-02-08 12:07:28

10

除非您使用super(...)构造函数调用其父项的空构造函数。 注意:它会在所有类中执行此操作,即使是扩展Object的类也是如此。

这不是继承,子类不会获得具有相同参数的相同构造函数。但是,您可以添加调用超类的构造函数之一的构造函数。

+0

“空构造函数”的意思是默认的构造函数,对吧? – user42155 2009-02-08 11:33:09

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); 
    } 
} 
1

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

2

Thumb规则是子类应该调用基类中的任何构造函数。所以如果你没有默认的const调用现有的子类。其他明智实现基类中的空常量,以避免编译问题

6

的基本规则是呼叫(或调用)的构造应该是第一个发言的是JVM需要执行,

所以,当你有一个只有参数化构造函数的超类,没有默认构造函数,并且基类没有显式调用超类的参数化构造函数,JVM提供了super();因为没有超类的默认构造函数,所以调用哪个抛出错误,所以要么在超类中提供默认构造函数,要么在基类构造函数中显式调用超类的参数化构造函数。当我们给出明确的调用时,JVM就不会打扰super();因为构造函数调用应该是该方法的第一个声明,不会发生(因为我们明确的调用)。

5

Java语言规范第8.8.9详细解释这是怎么回事:

如果一个类不包含任何构造函数声明,然后一个默认的构造 隐式声明。用于顶层类, 构件类,或局部类的默认构造的形式如下:

  • 默认构造具有相同的可访问性与类(6.6节)。
  • 默认构造没有正式的参数,除了在非私人 内部构件类,其中默认构造隐式声明表示类(§8.8.1, §15.9的立即封闭实例一个正式 参数。 2,§15.9.3)。
  • 默认的构造函数没有throws子句。
  • 如果声明的类是原始类Object,则构造函数的默认构造方法为空。否则,默认的构造函数只是 调用没有参数的超类构造函数。

你可以看到,有没有继承怎么回事:一切就是它是“神奇的编译器”与隐含声明的默认构造函数。该规范还明确指出,仅当类完全没有构造函数时才添加默认构造函数,这意味着您的问题的答案为“否”:一旦您给了一个类的构造函数,就可以访问其构造函数的默认构造函数超类丢失。

2

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

0

会有编译时错误......因为编译器会默认构造函数他超类,如果它不存在......它的错误...和程序将无法编译...