1

ここに、GRectと呼ばれるACMグラフィックライブラリのクラスを拡張する単純なクラスがあります。Grectは、GCanvas(ACMの一部でもあります)に描画できる基本的な長方形です。私が達成したいのは、長方形であるが、長方形と一緒に移動するラベルが付けられた新しいオブジェクトです。

私のコードでは、GRectを拡張するlabeledRectという名前のクラスを作成しました。これには、labeledRectsコンストラクターで初期化されるGLabel型のインスタンス変数「rectLabel」が含まれています。labledRectを移動すると、rectLabelも一緒に移動するように、GRectのメソッドの一部をオーバーライドしたいと思います。

私の問題は、「rectLabel」がインスタンス変数として宣言され、コンストラクターで初期化されているにもかかわらず、オーバーライドされたメソッド「setLocation」でNULLになることです。また、宣言時に「rectLabel」を初期化しようとしましたが、同じ問題が発生します。

import acm.graphics.*;

public class labeledRect extends GRect {

    //GLabel declared as an instance variable
    public GLabel rectLabel;

    public labeledRect(double x, double y, double width, double height, String theLabel) {
        //Call GRect constructor
        super(x, y, width, height);

        //Label initialized. 
        //Location setting and adding to the canvas works fine here. 
        rectLabel = new GLabel(theLabel);
        rectLabel.setLocation(
                    x + (width / 2) - (rectLabel.getWidth() / 2),
                    y + (height / 2) + (rectLabel.getAscent() / 2.2));
    }

    public void setLocation(double x, double y)
    {
        //Setting GRect's location. Works correctly./
        super.setLocation(x, y);

        //Attempt to set the label's location 
        //and get a NullPointer exception for rectLabel
        rectLabel.setLocation(
                super.getX() - (rectLabel.getWidth() / 2),
                super.getY() - (rectLabel.getHeight() / 2));
    }
}
4

1 に答える 1

2

パブリックフィールドであることを考えると、変数をnullに設定している可能性があるものを正確に推測するのは困難です。それが最初に変更する必要があることです。ほとんどの場合、フィールドはプライベートである必要があります。

setLocation次に、オーバーライドされたメソッドであると言います-それはGRectたまたまコンストラクターで呼び出されますか?その場合、コンストラクター内で値が設定されるに呼び出されます。これが問題の原因である可能性があります。labeledRect

Javaでは、スーパークラスコンストラクターは、サブクラス内のコードの前に実行されます。インスタンス変数初期化子とコンストラクター本体の両方の前に実行されます。すべての変数にはデフォルト値があります。これが、コンストラクターから仮想メソッドを呼び出すのは悪い考えである理由です。

(余談ですが、名前labeledRectはJavaの命名規則に従っていません。)

于 2012-08-19T20:50:05.833 に答える