我正在设计一个简单的类子类ArrayList<Color>
。在我的应用程序的上下文中,此列表充当“引用列表”,按照循环和明确定义的顺序返回Color
个对象。
@SuppressWarnings("serial")
public final class ColorList extends ArrayList<Color> {
private static int colorIndex = -1;
public ColorList() {
this.add(Color.CYAN);
this.add(Color.DARK_GRAY);
this.add(Color.GRAY);
this.add(Color.GREEN);
this.add(Color.BLUE);
this.add(Color.LIGHT_GRAY);
this.add(Color.MAGENTA);
this.add(Color.ORANGE);
this.add(Color.PINK);
this.add(Color.RED);
this.add(Color.YELLOW);
}
//if the color chosen is not the last one, increment index and get it.
public Color getNextColor() {
Color color = null;
if(colorIndex != this.size() - 1) {
color = this.get(++colorIndex);
}
else {
colorIndex = -1;
color = this.get(++colorIndex);
}
return color;
}
出于这个原因,我想让这个类不可变,因为它是一个只读列表,其内容是在对象首次实例化时定义的,并在整个生命周期内保持不变。与此同时,我需要能够利用getNextColor()
来保持“循环”的方式。
采取的方法
返回不可修改的引用。
public static List<Color> getInstance(){
return Collections.unmodifiableList(new ColorList());
}
这种方法的问题在于,通过返回List引用它
阻止我调用getNextColor()
方法,使我的课无用。
转换并不能解决问题,因为底层对象是一个
UnmodifiableRandomAccessList
的实例,无法转换为ColorList
。
覆盖涉及可选操作的方法
@Override
public boolean add(Color c) {
throw new UnsupportedOperationException("color list is read-only");
}
<overridding other methods such as addAll, remove...>
如documentation所述,根据收集的目的,可能会或可能不会实施一些标记为“可选”的操作。但是这会阻止我首先添加颜色,就像在实例化对象时在构造函数中那样。
我想我可能会误解一些关键的设计方面。有没有办法让我的类不可变,而不限制它(已经是基本的)功能?
编辑:为了向后兼容,这个类需要显式扩展ArrayList。因此,我不能使用包装类,即使我也认为它是最正确的方法。
答案 0 :(得分:2)
如果您希望List的内容是不可变的,那么您的构造函数类型有效,只有您应该调用super.add(...)
而不是this.add(...)
;这样做意味着在add(...)
上覆盖是明智的,可以保护列表免受外部干扰,同时允许构造函数为您初始化对象。
您的问题不清楚,但如果您还想阻止直接访问列表中的对象,您也可以明显地覆盖get(...)
和其他适当的方法 - 但如果您这样做,那么您的{{1} }方法应该调用getNextColor(...)
而不是super.get(...)
。
最后,你可能不需要this.get(...)
成员变量,因为你正在扩展一个List - 没有一点在其中嵌套另一个List。
答案 1 :(得分:2)
在你的情况下考虑使用组合而不是继承更好。在这种情况下,您只是不公开可以修改颜色列表的方法。
这是一个示例代码
public final class ColorList {
private final Color[] values;
private int colorIndex;
public ColorList(Color... colors) {
this.values = colors;
}
public Color getNextColor() {
if (colorIndex == values.length) colorIndex = 0;
return values[colorIndex++];
}
public static void main(String[] args) {
ColorList cl = new ColorList(Color.CYAN, Color.YELLOW, Color.WHITE);
System.out.println(cl.getNextColor());
System.out.println(cl.getNextColor());
System.out.println(cl.getNextColor());
System.out.println(cl.getNextColor());
}
}
您提供的源代码中有一些值得提及的时刻: