2

这就是我遇到问题的方式。我举个例子:

package check;

public class Check {
  int a,b;
  Check (int i,int j) {
    a = i;
    b = j;
  }
}

这可以。现在我想通过扩展来创建一个子类Check。所以我写道:

class V extends Check {

}

刚写完,Eclipse中就出现了一个叉号,点击后发现一条信息:

implicit super constructor Check() is undefined for default constructor. Must define an explicit constructor.

我用谷歌搜索了这个问题并添加了

V (int i, int j) {
  super(i, j);
}

Eclipse 也建议这样做。现在我有两个问题。

  1. 为什么必须使用构造函数class V?AFAIK,没有必要创建构造函数,因为 JAVA 编译器会自动创建默认构造函数来进行操作。同样从消息中,似乎还需要一个默认构造函数,但不是我写的,但正如我所说,JAVA不会自动创建它吗?
  2. 另一件事,我将子类中的代码更改为V(int i, int j){ super.a=i; super.b=j}.,但仍然出现错误。这是为什么?这段代码不是super.a=i; super.b=j和 一样super(i,j)吗?另外,在类 V 中,我可能不需要使用b,那为什么我需要通过构造函数对其进行初始化呢?
4

7 回答 7

6

1) 为什么必须为类 V 使用构造函数?AFAIK,没有必要创建构造函数,因为 JAVA 编译器会自动创建默认构造函数来进行操作。同样从消息中,似乎还需要一个默认构造函数,但不是我写的,但正如我所说,JAVA不会自动创建它吗?

仅当不存在其他构造函数时才创建默认构造函数,在创建构造函数Check(int i,int j)时删除了默认构造函数。

当您在构造函数中不包含对 super 的调用时,java 会尝试super()默认调用。但是,由于父类中没有默认构造函数,它不能这样做。

这种行为很好,因为您可能不需要默认构造函数;某些变量可能必须初始化才能使对象正确运行。因此,需要有一种方法来删除默认构造函数,这是通过显式创建构造函数来完成的。

2)另一件事,我将子类中的代码更改为 V(int i, int j){ super.a=i; super.b=j}.,但我仍然收到错误。这是为什么?这段代码不是 super.a=i; super.b=j 和 super(i,j) 一样吗?另外,在V类中,我可能不需要使用b,那为什么我需要通过构造函数来初始化它呢?

编码

V(int i, int j){ 
   super.a=i; super.b=j
}

仍然没有调用父构造函数,因此变为

V(int i, int j){ 
   super();
   super.a=i; super.b=j
}

又一次 super() 不存在

必须存在一些对 super 的调用才能“设置”对象的父部分,一直到 Object(所有对象都隐含地扩展)。因此,您不能仅仅因为您在子构造函数中做了等效的事情而省略父构造函数

于 2013-11-08T14:15:43.917 回答
4

1) 仅当您自己未定义任何构造函数时,编译器才会生成无参数构造函数。在类Check中,您定义了一个构造函数。

2) 如果您没有在您定义的构造函数中显式调用超类构造函数,编译器会生成对无参数构造函数的调用。由于类Check没有无参数构造函数,编译器无法生成调用,您必须自己编写。

您可能想知道为什么类的构造函数必须调用其父类的构造函数。这是为了确保在您尝试使用对象之前完全初始化对象:父构造函数可能会初始化对象的某些方面,而这些方面只能由自己访问,并且在创建对象时调用构造函数是确保正确的唯一方法初始化。

于 2013-11-08T14:15:31.463 回答
1

因为在 Java 中创建对象时,必须首先调用类超构造函数。由于您没有超构造函数的默认值并且您没有超类的默认构造函数,因此您需要为子类提供一个,它调用super(i, j)

于 2013-11-08T14:16:00.967 回答
0
Why is it compulsory to use a constructor at all for class V?

这是因为在检查类中,您显式使用了参数化构造函数,并且也是 V 类的超类,所以如果您没有提到参数化构造函数,那么如果您没有定义任何参数化构造函数,则需要显式调用 super()检查类中的构造函数,然后编译器将调用一个默认的无参数构造函数,它将在那里放置负责调用 Object 类构造函数的 super()。

于 2013-11-08T14:33:21.253 回答
0

当您创建一个类时,如果它没有构造函数,那么 Java 将为您提供一个默认构造函数。但是,如果您有 1 个或多个构造函数,则 Java 不提供此默认(或零参数)构造函数。

在您的子类中,您尚未创建任何构造函数,因此 java 为您提供了默认构造函数。在子类中,构造函数中有一个隐式调用super()。由于没有在超类中定义无参数构造函数,Java 正在有效地尝试调用尚不存在的构造函数。

于 2013-11-08T14:16:53.727 回答
0

认为它没有警告您,然后您编写了一段代码,例如:

V v = new V();

那么,你希望你的编译器表现什么?我的意思是,没有定义无参数的构造函数。您需要明确添加它。

Check() {

}
于 2013-11-08T14:17:29.230 回答
0

错误原因——

子类构造函数调用不带参数的父类构造函数。

Check类中没有不带参数的构造函数。

此外,

Java 编译器自动将super()构造函数插入到子类中。这个超级构造函数的含义是Go 并在父类中执行一个不带参数的构造函数

根据你的程序:

Check (int i,int j) {
    a = i;
    b = j;
}

当您运行程序编译器时,请删除默认构造函数,因为父类中的构造函数需要两个参数。

如果您不为您的V类添加构造函数,Java 编译器会自动插入默认构造函数。正如我之前所说,当您在默认构造函数中使用extends另一个 class( Check) 时,Java 编译器也会自动在默认构造函数的第一行插入super()

它看起来像这样:

class V extends Check {
   V(){super();}
}

我们可以super()以匹配父类中现有构造函数的方式添加到子类的构造函数。

在您的第二个问题中也super()自动插入。由于会发生编译错误,因此父类中没有匹配的构造函数。

注意:添加时super()必须是子类构造函数的第一行。

于 2017-05-18T14:31:03.713 回答