派生类的构造函数(Java)

时间:2014-09-28 17:21:00

标签: java oop inheritance constructor

我是Java的新手,并且想要提出一个基本问题。希望你们能帮助我。假设我有一个基础classe Super和一个派生类Sub,它继承了Super类,如下所示:

public class TestSuperSub {
  public static void main(String[] args) {
    Super ou = new Sub(5,10);
  }
}

class Super {
  Super() {
    System.out.println("Super()");
  }

  Super(int x, int y) {
    System.out.println("Super(int, int)");
  }
}

class Sub extends Super {
   public Sub(int x, int y) {
      System.out.println("Sub(int, int)");
   }
}

输出

Super()
Sub(int, int)

据我所知,你调用Sub :: Sub(int,int),因此打印Sub(int,int)。但是为什么要打印Super(),因为Super :: Super()从未被调用过?

有人可以向我解释一下。 非常感谢! 干杯

6 个答案:

答案 0 :(得分:1)

默认情况下,Java将调用超类的no-arg构造函数,除非您显式调用另一个构造函数。如果您想致电Super(int, int),则必须明确地致电:

public Sub(int x, int y) {
  super(x, y);
  System.out.println("Sub(int, int)");
}

答案 1 :(得分:0)

当你实例化一个类时,所有的超类层次结构也必须被实例化,并且它将通过自动为每个类提供的null构造函数来完成。

以下代码

public class Superclassing {

    public static void main(String[] args) {

        new C();
    }

    Superclassing() {   System.out.println("super");    }
}

class A extends Superclassing {

    A() {   System.out.println("A");    }
}

class B extends A {

    B() {   System.out.println("B");    }
}

class C extends B {

    C() {   System.out.println("C");    }
}

输出

super
A
B
C

这是通过Skeet的答案中提到的设计完成的,并且也在这里(奇怪的是,它在8.8.7中解释之前提到):

JLS 8.8.3. Constructor Modifiers

  

缺少 native 构造函数是一种随意的语言设计选择   这使得Java虚拟机的实现变得容易   验证是否始终正确调用超类构造函数   在对象创建期间

(强调我的。)

答案 2 :(得分:0)

  

但为什么要打印Super(),因为Super :: Super()从未被调用过?

它有,因为你的Sub构造函数是隐式地调用它。就像你写的那样:

public Sub(int x, int y) {
   super();
   System.out.println("Sub(int, int)");
}

来自section 8.8.7 of the JLS

  

构造函数体的第一个语句可能是对同一个类或直接超类(§8.8.7.1)的另一个构造函数的显式调用。

     

...

     

构造函数通过一系列涉及此的一个或多个显式构造函数调用直接或间接调用自身,这是一个编译时错误。

     

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

如果要调用其他超类构造函数,则需要隐式执行此操作。当你调用一个子类构造函数时,总是继续通过继承层次结构,在子类构造函数之前执行超类构造函数的主体...实际上,甚至子类中的字段初始化器只是在超类构造函数之后运行。

答案 3 :(得分:0)

它是Java中最基本的基本概念。它是超级关键字的魔力构造函数链接

浏览这些链接。希望这会帮助您理解这个概念。

http://docstore.mik.ua/orelly/java-ent/jnut/ch03_04.htm

http://docs.oracle.com/javase/tutorial/java/IandI/super.html

答案 4 :(得分:0)

默认在子类的构造函数中 如果没有提到**

的构造函数,则第一行是调用基类的默认构造函数(隐式)
  

超级();

** 如果你写

  

超级(X,Y);

然后将调用其他构造函数

注意:构造函数的第一行是调用基类构造函数。 如果没有超类,那么 Object 类的构造函数被称为

答案 5 :(得分:0)

class A{
A(){
    System.out.println("no-arg constructor in A");
}

A(int a){
    System.out.println("parameterized constructor in A");
}
}

class B extends A{
B(){

    System.out.println("no-arg constructor in B");
}

B(int b){
            //by default during compilation super() keyword will be added in first line of this constructor
    System.out.println("paramterized constructor in B");
}

}
public class TestDemo {
public static void main(String[] args) {
    B aVar = new B(10); 
    aVar = new B();

}

}

Output:
  // output for first object i.e, new B(10)
   no-arg constructor in A
   paramterized constructor in B
  //output for second object i.e, new B()
   no-arg constructor in A
   no-arg constructor in B

编译期间编译器默认添加一个super()关键字,具体取决于您在main方法中创建的Object。