以下设置:
public class Superclass
{
private String params;
public Superclass(String params)
{
this.params = params;
doStuff();
}
public void doStuff()
{
// uninteresting stuff
}
}
public class Subclass extends Superclass
{
private Object someObject;
public Subclass(String params, Object someObject)
{
super(params);
this.someObject = someObject;
}
@Override
public void doStuff()
{
someObject.toString(); // <- causes NullPointerException
}
}
超类创建一个用户界面,而子类应该创建一个更专业的版本。
从软件工程的角度来看,当"子类"仍然扩展"超类"时,防止NullPointerException
的最干净方法是什么?
父类在构造时没有明显的理由调用doStuff
。
简单地说,不要把电话放在那里。 这些类应彼此独立地构造。 父类不应依赖于来自子类的任何数据来完成其构造;在父构造函数中调用的子项重写的任何方法都将引入此依赖项。
但是,如果您确实发现需要在父级中调用额外的方法,则可以创建一个final
方法,并且不会发生不良影响,因为子方法无法访问该方法。
public class Superclass {
private String params;
public Superclass(String params) {
this.params = params;
doStuffParent();
}
public final void doStuffParent() {
// uninteresting stuff
}
public void doStuff() {
// uninteresting stuff...again?
}
}
从软件工程的角度来看,您正在尝试对尚未构造的对象执行操作。将这个想法映射到你的真实类及其工作,你会明白超类构造函数存在一些问题,因为它试图在一个糟糕的状态下工作。
话虽如此,您有几个选择。
- 如果有意义,请尝试将
Object someObject
传递给超类。 可能是超级类真的需要它才能工作。 - 不要在超类构造函数中调用
doStuff()
。在两个构造函数之外显式调用它甚至可能是有意义的。 - 让扩展类的构造函数调用
doStuff(..)
。