在对超类构造函数的超级调用中使用子类方法作为参数
Using subclass method as parameter in super call to superclass constructor
在我下面的代码中,我试图在 RandomLetterChooser 子类构造函数中调用 RandomStringChooser 构造函数。
为了传递一个数组作为参数,我调用了super()中的getSingleLetters方法。但是,我收到以下错误:
"cannot reference this before superclass constructor has been called"
带有指向 getSingleLetters(子类的第 3 行)中的 "g" 的箭头。
为什么会这样,我应该如何解决?
仅供参考:这是我对 1.b 的尝试解决方案。 AP 计算机科学 2016 FRQ (https://secure-media.collegeboard.org/digitalServices/pdf/ap/ap16_frq_computer_science_a.pdf)。
他们的解决方案(https://secure-media.collegeboard.org/digitalServices/pdf/ap/apcentral/ap16_compsci_a_q1.pdf)涉及一个 ArrayList(或 List,我不完全确定这两者之间的区别),我意识到它更清晰,但仍然以与我相同的方式调用 getSingleLetters 方法在下面完成(因此在 运行 时应该有相同的错误)。
class RandomStringChooser {
private int length;
private int count = 0;
private String word;
private String newArray[];
RandomStringChooser(String[] array) {
length = array.length;
newArray = new String[length];
for(int i = 0; i < length; i++) {
newArray[i] = array[i];
}
}
String getNext() {
if(count == length) return "NONE";
word = "";
while(word.equals("")) {
int index = (int) (Math.random() * length);
word = newArray[index];
newArray[index] = "";
}
count++;
return word;
}
}
class RandomLetterChooser extends RandomStringChooser{
RandomLetterChooser(String str) {
super(getSingleLetters(str)); //here's the problem
}
String[] getSingleLetters(String str) {
String[] letterArray = new String[str.length()];
for(int i = 0; i < str.length(); i++) {
letterArray[i] = str.substring(i, i+1);
}
return letterArray;
}
}
这里是我 运行 程序的地方,以防它有帮助:
public class AP2 {
public static void main(String[] args) {
String ball = "basketball";
RandomLetterChooser s = new RandomLetterChooser(ball);
for(int i = 0; i < 12; i++) {
System.out.print(s.getNext() + " ");
}
}
}
"cannot reference this before superclass constructor has been called"
在(如您所做的那样)期间调用任何实例方法
RandomLetterChooser(String str) {
super(getSingleLetters(str)); //here's the problem
}
或在调用超级 class 构造函数之前导致编译错误。
An explicit constructor invocation statement in a constructor body may
not refer to any instance variables or instance methods or inner
classes declared in this class or any superclass, or use this or super
in any expression; otherwise, a compile-time error occurs.
或者换句话说,当这个层次结构(父class)还没有完全构建时,一个对象不能被使用(实例字段和方法)。
通过将 getSingleLetters()
方法的修饰符更改为 static
您可以使用此代码,因为 static
方法未关联到 class 的实例:
RandomLetterChooser(String str) {
super(RandomLetterChooser.getSingleLetters(str)); //here's the problem
}
这是因为
getSingleLetters 方法
在完成超类构造函数之前无法使用。实际上,我的意思与异常文本相同。所以你可以把这个方法放到你的超类构造函数中或者看看这里:
Is it possible to do computation before super() in the constructor?
正如其他答案所解释的那样 - 这是应该发生的事情。
你看到一个新对象的 "construction" 只在 那个 class 的构造函数完全完成之后才完成 - 其中包括超级 class构造函数。只有这样您才能确定您的对象已完全初始化。
换句话说:您绝对不想像您的示例代码那样做事:避免在您的 class 上调用 "real" 方法,而 它还处于初始化阶段!
在我下面的代码中,我试图在 RandomLetterChooser 子类构造函数中调用 RandomStringChooser 构造函数。
为了传递一个数组作为参数,我调用了super()中的getSingleLetters方法。但是,我收到以下错误:
"cannot reference this before superclass constructor has been called"
带有指向 getSingleLetters(子类的第 3 行)中的 "g" 的箭头。
为什么会这样,我应该如何解决?
仅供参考:这是我对 1.b 的尝试解决方案。 AP 计算机科学 2016 FRQ (https://secure-media.collegeboard.org/digitalServices/pdf/ap/ap16_frq_computer_science_a.pdf)。 他们的解决方案(https://secure-media.collegeboard.org/digitalServices/pdf/ap/apcentral/ap16_compsci_a_q1.pdf)涉及一个 ArrayList(或 List,我不完全确定这两者之间的区别),我意识到它更清晰,但仍然以与我相同的方式调用 getSingleLetters 方法在下面完成(因此在 运行 时应该有相同的错误)。
class RandomStringChooser {
private int length;
private int count = 0;
private String word;
private String newArray[];
RandomStringChooser(String[] array) {
length = array.length;
newArray = new String[length];
for(int i = 0; i < length; i++) {
newArray[i] = array[i];
}
}
String getNext() {
if(count == length) return "NONE";
word = "";
while(word.equals("")) {
int index = (int) (Math.random() * length);
word = newArray[index];
newArray[index] = "";
}
count++;
return word;
}
}
class RandomLetterChooser extends RandomStringChooser{
RandomLetterChooser(String str) {
super(getSingleLetters(str)); //here's the problem
}
String[] getSingleLetters(String str) {
String[] letterArray = new String[str.length()];
for(int i = 0; i < str.length(); i++) {
letterArray[i] = str.substring(i, i+1);
}
return letterArray;
}
}
这里是我 运行 程序的地方,以防它有帮助:
public class AP2 {
public static void main(String[] args) {
String ball = "basketball";
RandomLetterChooser s = new RandomLetterChooser(ball);
for(int i = 0; i < 12; i++) {
System.out.print(s.getNext() + " ");
}
}
}
"cannot reference this before superclass constructor has been called"
在(如您所做的那样)期间调用任何实例方法
RandomLetterChooser(String str) {
super(getSingleLetters(str)); //here's the problem
}
或在调用超级 class 构造函数之前导致编译错误。
An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.
或者换句话说,当这个层次结构(父class)还没有完全构建时,一个对象不能被使用(实例字段和方法)。
通过将 getSingleLetters()
方法的修饰符更改为 static
您可以使用此代码,因为 static
方法未关联到 class 的实例:
RandomLetterChooser(String str) {
super(RandomLetterChooser.getSingleLetters(str)); //here's the problem
}
这是因为
getSingleLetters 方法
在完成超类构造函数之前无法使用。实际上,我的意思与异常文本相同。所以你可以把这个方法放到你的超类构造函数中或者看看这里:
Is it possible to do computation before super() in the constructor?
正如其他答案所解释的那样 - 这是应该发生的事情。
你看到一个新对象的 "construction" 只在 那个 class 的构造函数完全完成之后才完成 - 其中包括超级 class构造函数。只有这样您才能确定您的对象已完全初始化。
换句话说:您绝对不想像您的示例代码那样做事:避免在您的 class 上调用 "real" 方法,而 它还处于初始化阶段!