Java构造函数继承?

时间:2013-03-30 18:09:55

标签: java inheritance constructor

我一直认为构造函数不是继承的,但请看这段代码:

class Parent {
    Parent() {
        System.out.println("S1");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("S2");
    }
}

public class Test5 {
    public static void main(String[] args) {
        Child child = new Child();
    }
}

//RESULT:
//S1
//S2

它显示Child继承了构造函数。为什么结果有S1?有没有可能创建没有参数的2个构造函数,并且在没有基础构造函数的结果中只有Child构造函数(只有S2)?

7 个答案:

答案 0 :(得分:16)

无论你在这里看到什么,都被称为构造函数链接。现在什么是构造函数链接:

  

构造函数链接通过使用继承来实现。一个子类   构造函数方法的第一个任务是调用它的超类'构造函数   方法。这可确保创建子类对象   在继承中初始化它上面的类   链

     

继承链中可能有任意数量的类。一切   构造函数方法将调用链直到顶部的类   已达到并初始化。然后下面的每个后续课程都是   初始化为链回归到原始子类。   此过程称为构造函数链接。(Source

这就是你的计划中发生的事情。编译程序时,Child编译为javac

class Child extends Parent 
{ 
  Child()
  {
    super();//automatically inserted here in .class file of Child
    System.out.println("S2");
  }
}

您的Parent类将转换为以下内容:

Parent() 
{
    super();//Constructor of Object class
    System.out.println("S1");
}

这就是您的输出显示为:

的原因
S1 //output from constructor of super class Parent
S2 //output from constructor of child Class Child

答案 1 :(得分:2)

Java doc说:

  

子类继承所有成员(字段,方法和嵌套   来自其超类的类)。构造者不是成员,所以他们   不是由子类继承,而是超类的构造函数   可以从子类调用。

如果您没有声明任何类型的构造函数,则会添加默认值。

如果你没有在子类的第一行调用任何其他构造函数,则会调用super()。

答案 2 :(得分:1)

  

不继承构造函数。

超类构造函数不会在派生类中继承。

  

是否有可能创建没有参数的2个构造函数,并且在没有基础构造函数的结果中只有Child构造函数。

不,它不可能在Java中每个派生类构造函数都调用超类构造函数。如果你不添加它,则调用无参数构造函数。

public SuperClass() {
   ...
}

public DerivedClass() {
  //Compiler here call no argument constructor of Super class.
}

答案 3 :(得分:0)

你写道:

  

它显示Child继承了构造函数。

构造函数不能被继承。类可以继承,因此Child不会继承任何构造函数。 Child继承了Parent类。 Parent继承类Object。当您调用子构造函数时,在运行子构造函数的代码之前,会自动调用Object构造函数,然后调用Parent构造函数。

这就是你得到这个结果的原因:

S1
S2

答案 4 :(得分:0)

除非定义了显式构造函数,否则构造函数将始终调用其超类构造函数。来自Java Language Specification

  

如果构造函数体不是以显式构造函数调用开始并且声明的构造函数不是原始类Object的一部分,那么构造函数体隐式地以超类构造函数调用“super();”开头,调用它的直接超类的构造函数,不带参数。

答案 5 :(得分:0)

如果超类没有默认的构造函数,则子类也需要定义一个显式的构造函数。否则将抛出编译时异常。在子类构造函数中,在这种情况下,必须调用超类构造函数,并且它应该是子类构造函数中的第一条语句。

答案 6 :(得分:0)

public class HelloWorld{

    private static class A {
        A(String x) {
            System.out.println(x);
        }
    }
    
    private static class B extends A {
        
    }

    public static void main(String []args){
        B b =  new B();
        System.out.println("Hello World");
    }
}

输出:

/*
error: constructor A in class A cannot be applied to given types;
    private static class B extends A {
                   ^
  required: String
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error
*/

所以这意味着构造函数从不继承

因此,这里发生的是 B类的参数较少的构造函数尝试调用 A类的参数较少的构造函数,但是没有发现,因此给了它错误。

如果我们在 A类中添加较少参数的构造函数,则该程序将正常运行。