Java编程语言第4版练习3.3



我花了很长时间思考这个练习,我无法理解这个问题的含义。本节讨论了扩展类,以及当从扩展类构造对象时,事情发生的顺序。

创建对象时,会为其所有字段分配内存,包括从超类继承的字段,并且这些字段被设置为其各自类型的默认初始值(所有数值类型为零,false对于布尔值,'\u0000'表示char,null表示对象引用)。在此之后,建筑有三个阶段:

  1. 调用超类的构造函数
  2. 使用字段的初始化器和任何初始化块初始化字段
  3. 执行构造函数的主体

。。。

练习3.3:如果在建筑,你如何解决这些问题?

代码:

class X {
protected int xMask = 0x00ff;
protected int fullMask;
public X() {
fullMask = xMask;
}
public int mask(int orig) {
return (orig & fullMask);
}
}
class Y extends X {
protected int yMask = 0xff00;
public Y() {
fullMask |= yMask;
}
}

我认为这个练习是为了说明实例化Y时会发生什么,即Y y = new Y();。我认为他们没有很好地解释这一切,因为第2项没有描述它所指的字段(类或超类)。如果将代码放入调试器并在不同的语句处停止,则在执行上述语句时会发现以下执行顺序:

  1. Y的构造函数被调用,即执行控制传递到Y的构造函数的开始
  2. X的构造函数被调用
  3. X的变量初始化是执行的,所以xMask得到0x00ff
  4. X的构造函数语句被执行,因此fullMask获取xMask值
  5. 执行Y的变量初始化,因此yMask得到0xff00
  6. 执行Y的构造函数语句,因此fullMask使用yMask获得fullMask

所以这将是预期的行为-无论X对变量等做什么,都是在Y获得任何控制之前完成的;Y不应该"知道"X是如何实现的,它只应该使用X,因为它(希望)被记录为行为。

我希望这能有所帮助。我不喜欢这本书把这种行为描述为"问题";我看不出这里有什么"问题"。为了编写扩展X的Y,您需要注意X行为中影响您的外部可见部分。在这种情况下,X给fullmask一个特定的值,您可以在Y构造函数中使用该值。

最新更新