5

我正在阅读的书中的文字总结

“从技术上讲,构造函数不能被覆盖,因为它们与当前类具有相同的名称。新的构造函数被创建而不是被继承。这个系统工作正常;......”

我不明白的部分是当他们这样说时:

“当您的类的构造方法被调用时,所有超类的具有相同签名的构造方法也被调用。因此,您继承的类的所有部分都可能发生初始化”

我不明白的是相同的签名部分......它让我觉得好像所有的构造函数都必须具有相同的签名,然后当你初始化一个子类对象时,它的所有超类都将被自动调用而不是必须为每个子类调用 super(arg1,arg2) ......这是他们所说的吗?

4

3 回答 3

10

这不太对。只有当它是默认构造函数(即无参数构造函数)时,才会自动调用超类的构造函数。

如果你的超类没有默认构造函数,那么你必须显式调用你选择的构造函数super(args..)

例如,尽管BearManPig' 构造函数的签名与 ' 不同,但这完全没问题Animal

public class Animal {
  public Animal() {
  }
}

public class BearManPig extends Animal {
  public BearManPig(String string) {
  }
}

那是因为有一个 Java 找到了默认的无参数构造函数。

现在,当没有默认构造函数时,您必须明确要调用哪个构造函数。例如,这不起作用

// DOESN'T COMPILE
public class Animal {
  public Animal(String string) {
  }

  public Animal(String string0, String string1) {
  }
}

public class BearManPig extends Animal {
   // There is no default constructor, stupid Java can't figure out what to do
  public BearManPig(String string) {
  }
}

但这确实:

// does compile
public class Animal {
  public Animal(String string) {
  }

  public Animal(String string0, String string1) {
  }
}

public class BearManPig extends Animal {
  public BearManPig(String string) {
    super(string); // I've told Java what to do
  }
}
于 2012-06-16T15:57:28.090 回答
4

所有超类不需要具有相同的构造函数签名。
当您创建新对象时,如果没有定义构造函数,Java 将不调用超类的参数构造函数。如果您不定义任何其他构造函数,Java 不会提供参数构造函数。
如果您定义任何其他构造函数,则必须在子类构造函数中调用它(在第一行)。
可能会有所帮助。

于 2012-06-16T15:57:52.760 回答
2

当你的类的构造方法被调用时,所有超类的具有相同签名的构造方法也被调用。因此,您继承的类的所有部分都可能发生初始化

这是不正确的。首先,关于术语的说明:构造函数不是方法,因此术语“构造函数方法”没有任何意义。

虽然确实调用了超类构造函数,但它不需要具有相同的签名。如果子类构造函数以超类构造函数调用表达式开头,例如

class Student extends Person {
    public Student(String name) {
        super(name, Occupation.STUDENT);
    }
}

与调用的参数计数和类型匹配的超类构造函数。您完全可以自由地将哪些参数传递给该构造函数。

如果子类构造函数不以超构造函数调用表达式开头,编译器将为您插入对超类的可访问零参数构造函数的调用 - 如果没有这样的构造函数,则引发编译错误。

Sams 现在在 21 天内自学 Java 2

您知道 Java 2 已经过时十年了吗?任何一本这么老的书都会教你一些过时的东西,你最好快点忘记。为什么不使用更现代的书?

于 2012-06-16T16:09:55.340 回答