繁体   English   中英

在超类构造函数的超级调用中使用子类方法作为参数

[英]Using subclass method as parameter in super call to superclass constructor

在下面的代码中,我试图在RandomLetterChooser子类构造函数中调用RandomStringChooser构造函数。

为了传递一个数组作为参数,我在super()中调用了getSingleLetters方法。 但是,我收到以下错误:

“在调用超类构造函数之前无法引用它”

用箭头指向getSingleLetters中的“g”(子类的第3行)。

为什么会这样,我该如何解决?

仅供参考:这是我尝试解决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() + " ");
        }
    }
}

“在调用超类构造函数之前无法引用它”

(在你做的时候)调用任何实例方法

RandomLetterChooser(String str) {
    super(getSingleLetters(str)); //here's the problem
}

或者在调用超类构造函数之前导致编译错误。

JLS第8章类

构造函数体中的显式构造函数调用语句可能不引用 此类或任何超类中声明的 任何实例变量或实例方法或内部 ,或者在任何表达式中使用this或super; 否则,发生编译时错误

或者以另一种方式说,在没有完全构造这个层次结构(父类)的情况下,不能使用对象(实例字段和方法)。

通过将getSingleLetters()方法的修饰符更改为static您可以使用此代码,因为static方法与类的实例无关:

 RandomLetterChooser(String str) {
    super(RandomLetterChooser.getSingleLetters(str)); //here's the problem
}

正如其他答案所解释的那样 - 这是应该发生的事情。

您会看到新对象的“构造”仅该类的构造函数完全完成后才完成 - 并且包括超类构造函数。 只有这样,您才可以确定您的对象已完全初始化。

换句话说:你绝对不想做的事情一样你的示例代码:避免调用你的类“真实”的方法,同时仍处于初始化阶段!

这是因为

getSingleLetters方法

在使用超类构造函数之前无法使用。 实际上我的意思与例外文本相同。 所以你可以把这个方法放到你的超类构造函数中,或者看看这里:

是否可以在构造函数中的super()之前进行计算?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM