Переменная экземпляра, инициализированная в конструкторе класса, становится недействительной в переопределенном методе

Здесь у меня есть простой класс, который расширяет класс в графической библиотеке ACM под названием GRect. Grect - это основной прямоугольник, который можно нарисовать в GCanvas (также является частью ACM). Чего я хочу добиться, так это нового объекта, который представляет собой прямоугольник, но имеет прикрепленную метку, которая перемещается вместе с прямоугольником.

В моем коде я создал класс с именем labeledRect, который расширяет GRect и содержит переменную экземпляра "rectLabel", имеющую тип GLabel, которая инициализируется в конструкторе labeledRects. Я хочу переопределить некоторые из методов GRect, чтобы при перемещении labledRect с ним перемещался rectLabel.

Моя проблема заключается в том, что несмотря на то, что "rectLabel" объявляется как переменная экземпляра и инициализируется в конструкторе, он становится NULL в переопределенном методе "setLocation". Я также попытался инициализировать "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));
    }
}

1 ответ

Решение

Трудно рассуждать о том, что именно может устанавливать переменную в null, учитывая, что это открытое поле. Это первое, что вы должны изменить. Поля почти всегда должны быть приватными.

Далее вы говорите setLocation это переопределенный метод - он вызывается в GRect конструктор случайно? Если так, это будет вызвано до того, как значение будет установлено в пределах labeledRect конструктор, который вполне может быть причиной вашей проблемы.

В Java конструктор суперкласса выполняется перед любым кодом в подклассе - как перед инициализаторами переменных экземпляра, так и перед телом конструктора. Все переменные будут иметь свои значения по умолчанию. Вот почему плохая идея вызывать виртуальные методы из конструкторов.

(В сторону, название labeledRect не следует соглашениям об именах Java.)

Другие вопросы по тегам