构造函数是否未绑定到类的实例?

时间:2015-03-27 17:08:31

标签: java inheritance polymorphism superclass

当从子类调用super()时,它会在'this'对象上调用,即由语句new Subclass()创建的对象。在'this'对象上调用super()。但'this'对象包含所有变量,超类的方法及其本身及其构造函数,但不包含超类构造函数。那么如何在'this'对象上调用super()?

请参阅附件中我试图解释我的理解。

注意:P是超类,Q是派生类enter image description here

4 个答案:

答案 0 :(得分:6)

  

但是'这个' object contains ...不是超类构造函数。

它包含"包含"超类构造函数(只要它"包含"任何方法,有点手工波浪) - 它只是唯一方式来调用超级构造函数是使用super(..)语法及其约束(具体来说,它必须是子类的构造函数的第一个语句)。

在那挥手:一个物体实际上并没有包含一种方法。方法是在参数上调用的静态事物,当您调用this.foo()时,它基本上被(由JVM)转换为foo(this)。名称this实际上只是&#34的特殊名称;该方法的第一个参数,恰好是我期望的this。"

构造函数的工作方式完全相同。 new Foo()分配一些内存,将其变量初始化为默认值(0 / null),然后调用Foo.<init>(<a reference to the new chunk of memory>)。如果Foo构造函数调用super(),则Foo.<init>中的第一个语句基本上是FooSuperClass.<init>(this)

这不是Java语法的工作原理,但它基本上是在发生什么。

实际上,请查看这段Java代码:

// in Super.java
public class Super {}

// in Sub.java
public class Sub extends Super {}

如果你javap -c Sub,你会看到:

Compiled from "Sub.java"
public class Sub extends Super {
  public Sub();
    Code:
       0: aload_0
       1: invokespecial #1        // Method Super."<init>":()V
       4: return
}

这是做什么的?在0它将第一个参数推送到Sub()构造函数(又名this)到堆栈,然后在1它调用Super.<init>,这将弹出参数并将其传递给Super.<init>方法。 (最后,在4返回。)

答案 1 :(得分:3)

'this'对象确实包含超类构造函数。

因为QP的子类(或派生类),Q可以访问相同的方法,字段和构造函数确实。就super()的实例而言,Q构造函数将构造P的实例。在使用super()之后,必须进行任何其他初始化。请注意,super()必须是构造函数中的第一行,如果您要使用它。

public Q()
{
    super();
    //other TO-DO...
}

答案 2 :(得分:2)

在java中,只要实例化子类,就会隐式调用其超类构造函数。这是因为,父类需要首先进行初始化,以确保派生类具有所有这些值。

答案 3 :(得分:2)

始终定义默认构造函数(即没有参数的构造函数)。

  

您不必为您的班级提供任何构造函数,但在执行此操作时必须小心。编译器自动为没有构造函数的任何类提供无参数的默认构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会抱怨,因此您必须验证它是否存在。如果你的类没有显式的超类,那么它有一个隐式的超类Object,它有一个无参数的构造函数。

请参阅:https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

此构造函数将始终被隐式调用,但您也可以显式调用它。

如果你向P添加一个构造函数P(String foo, int bar),你将不得不在Q中调用该构造函数:

public class Q {
   public Q() {
       super("answer", 42);
   }
}