只是因为protected
或public
non-final方法是由子类覆盖,这是脚步到初始化问题。假设重写方法试图在初始化之前访问一个字段,你会得到一个NullPointerException
。假设它调用另一种方法,它依赖于在完全初始化之前不能保证的特定对象状态,这会导致程序更加微妙的错误或不正确。
我要说的是已经在你的书了,所以让我们添加一个具体的例子:
public SpaceShip {
private double oilLevelInLitres;
private String model;
public SpaceShip(double oilLevelInLitres, String model) {
this.oilLevelInLitres = oilLevelInLitres;
displayOilLevel();
this.model = model;
}
public void displayOilLevel() {
System.out.println("Oil level is currently " + oilLevelInLitres + " litres");
}
}
public SpaceShipWithSecondaryReservoir {
public SpaceShip(double oilLevelInLitres, double secondaryReservoirOilLevelInLitres, String oilLevelInLitres) {
super(oilLevelInLitres, oilLevelInLitres);
this.secondaryReservoirOilLevelInLitres = secondaryReservoirOilLevelInLitres;
}
public void displayOilLevel() {
System.out.println("Model " + model + " oil level is currently " + oilLevelInLitres +
" litres and " + secondaryReservoirOilLevelInLitres + " litres in the seconday reservoir");
}
}
public Main() {
public static void main(String[] args) {
// will print "Model null oil level is currently 17.0 litres and 5.0 litres in
// the secondary reservoir"
new SpaceShipWithSecondaryReservoir(17, 5, "Falcon-3X");
}
}
在这个例子中,你可能会说,父类也可以初始化model
名调用方法前,而且你是对的,但是现在程序员编写了父类构造函数,他假定显示方法不需要除油位以外的任何其他状态。
这是一个编程错误,通过在构造函数的末尾调用display方法可以避免,但在更复杂的情况下,它不会那么简单和明显。在构造函数中调用可重写的方法会让您遇到一类在您只调用final或private方法时不存在的错误。
我已经添加了一个例子来说明 – Dici