【问题标题】:Java constructor inheritance?Java构造函数继承?
【发布时间】:2013-03-21 05:56:44
【问题描述】:
我一直以为构造函数不是继承的,但是看看这段代码:
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 个没有参数的构造函数,并且在没有基本构造函数的结果上只有子构造函数(只有 S2)?
【问题讨论】:
标签:
java
inheritance
constructor
【解决方案1】:
您在此处看到的任何内容都称为构造函数链接。现在什么是构造函数链:
构造函数链接通过使用继承发生。一个子类
构造方法的第一个任务是调用它的超类的构造方法
方法。这确保了子类对象的创建开始
在继承中初始化它上面的类
链。
在一个继承链中可以有任意数量的类。每一个
构造方法将调用链直到顶部的类
已达到并初始化。然后下面的每个后续课程都是
当链回到原始子类时初始化。
这个过程称为构造函数链接。(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
【解决方案2】:
Java 文档说:
子类继承所有成员(字段、方法和嵌套
类)来自其超类。构造函数不是成员,所以他们
不是子类继承的,而是超类的构造函数
可以从子类中调用。
如果您不声明任何类型的构造函数,则会添加默认值。
如果您没有在子类的第一行调用任何其他构造函数,则会调用 super()。
【解决方案3】:
你写:
说明 Child 继承了构造函数。
构造函数不能被继承。类可以被继承,所以 Child 不继承任何构造函数。 Child继承类Parent。 Parent 继承类 Object。当您调用 Child 构造函数时,在运行 Child 构造函数的代码之前,会自动调用 Object 构造函数,然后调用 Parent 构造函数。
这就是你得到这个结果的原因:
S1
S2
【解决方案4】:
构造函数没有被继承。
派生类中不继承超类构造函数。
是否有可能创建 2 个没有参数的构造函数,并且在没有基本构造函数的结果上只有子构造函数。
不,不可能在 Java 中,每个派生类构造函数都调用超类构造函数。如果不添加,则调用无参数构造函数。
public SuperClass() {
...
}
public DerivedClass() {
//Compiler here call no argument constructor of Super class.
}
【解决方案5】:
除非已定义显式构造函数,否则构造函数将始终调用其超类构造函数。来自Java Language Specification:
如果构造函数体不是以显式构造函数调用开始,并且被声明的构造函数不是原始类 Object 的一部分,则构造函数体隐式以超类构造函数调用“super();”开始,调用其直接超类的构造函数,不带参数。
【解决方案6】:
如果超类没有默认构造函数,那么子类也需要定义一个显式构造函数。否则会抛出编译时异常。在子类构造函数中,这种情况下必须调用超类构造函数,它应该是子类构造函数中的第一条语句。
【解决方案7】:
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
*/
这意味着构造函数是从不继承
因此,这里发生的情况是 class B's 参数少的构造函数尝试调用 class A's 参数的构造函数,但它没有发现因此给出错误。
如果我们在class A中添加参数少的构造函数,那么这个程序就可以正常工作了。