这里我有一个简单的类,它扩展了一个名为GRect的ACM图形库中的类。 Grect是一个基本矩形,可以绘制到GCanvas(也是ACM的一部分)。 我想要实现的是一个新的对象,它是一个矩形,但有一个随矩形移动的附加标签。
在我的代码中,我创建了一个名为labeledRect的类,它扩展了GRect,并包含一个类型为GLabel的实例变量“rectLabel”,它在labeledRects构造函数中初始化。我想覆盖一些GRect的方法,以便在labledRect被移动时,rectLabel随之移动。
我的问题是,尽管“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));
}
}
答案 0 :(得分:2)
由于它是一个公共字段,因此很难确定将变量设置为null的确切内容。这是你应该改变的第一件事。字段应该始终是私有的。
接下来,你说setLocation
是一个被重写的方法 - 是否有机会在GRect
构造函数中调用它?如果是这样,那么在{/ 1}}构造函数中设置值之前,将被称为,这很可能是导致问题的原因。
在Java中,超类构造函数在子类中任何代码之前执行 - 在实例变量初始化器和构造函数体之前。 所有变量都将具有默认值。这就是为什么从构造函数调用虚方法是个坏主意。
(另外,名称labeledRect
不遵循Java命名约定。)