首先,我很抱歉问题标题,但我想不出更好的方法来描述我的问题。随意改变它:)
假设我有这个抽象类Box
,它在一些私有变量上实现了几个构造函数,方法和其他东西。然后我有几个子类,如BoxA
和BoxB
。这两个都实现了额外的东西。
现在我有另一个抽象类Shape
和一些子类,如Square
和Circle
。
对于BoxA
和BoxB
,我需要有Shape
个对象的列表,但我需要确保只有Square
个对象进入BoxA
列表中只有Circle
个对象进入BoxB
列表。
对于该列表(在每个方框中),我需要使用get()
和set()
方法以及addShape()
和removeShape()
方法。
要知道的另一件重要事情是,对于每个创建的框,BoxA
或BoxB
,每个Shape
列表都完全相同。假设我创建了一个名为Square
的{{1}}列表和一个名为ls
和BoxA
的{{1}}个对象列表。无论如何,boxA1
和boxA2
都必须具有相同的boxA1
列表。
这是我的想法:
boxA2
由于该类型的对象的列表需要相同,我将其声明为ls
,并且与该列表一起使用的所有方法也是public abstract class Box {
// private instance variables
public Box() {
// constructor stuff
}
// public instance methods
}
public class BoxA extends Box {
// private instance variables
private static List<Shape> list;
public BoxA() {
// constructor stuff
}
// public instance methods
public static List<Square> getList() {
List<Square> aux = new ArrayList<Square>();
for(Square s : list.values()) {
aux.add(s.clone()); // I know what I'm doing with this clone, don't worry about it
}
return aux;
}
public static void setList(List<Square> newList) {
list = new ArrayList<Square>(newList);
}
public static void addShape(Square s) {
list.add(s);
}
public static void removeShape(Square s) {
list.remove(list.indexOf(s));
}
}
。现在,对于static
,对于列表内容,类几乎是相同的。我只会将static
替换为BoxB
,问题就解决了。因此,对于创建的每个Square
对象,列表将只有一个且相同。对于每个创建的Triangle
对象都会发生相同的情况,但当然会使用不同类型的列表。
那么,你问我的问题是什么?好吧,我不喜欢代码... BoxA
,BoxB
,getList()
和setList()
方法基本上重复了addShape()
和{{1 ,只有列表将容纳的对象的类型是不同的。我想以某种方式避免所有这些方法“重复”。
我想不出在超类removeShape()
中这样做的方法。尝试使用BoxA
代替BoxB
或Box
进行静态处理也行不通,因为列表只适用于所有Shape
和Square
}对象,我需要它只有一个,但是Triangle
的每个子类。
我怎么能以不同的方式更好地做到这一点?
PS:我无法描述我的真实例子,因为我不知道我正在做的事情的英文正确的单词,所以我只使用了一个盒子和形状的例子,但它基本相同。答案 0 :(得分:1)
您可以尝试以下方式:
abstract class Box<E extends Shape> {
abstract protected List<E> getList();
abstract protected void setList(List<E> list);
protected static <T extends Shape> List<T> getCommon(Box<T> box) {
List<T> aux = new ArrayList<T>();
for (T s : box.getList()) {
aux.add((T) s.clone());
}
return aux;
}
protected static <T extends Shape> void setCommon(Box<T> box, List<T> newList) {
// do something on newList here if needed as common functionality
box.setList(new ArrayList<T>(newList));
}
}
class BoxA extends Box<Square> {
private static List<Square> list;
@Override
protected List<Square> getList() {
return list;
}
@Override
protected void setList(List<Square> list) {
this.list = list;
}
public static List<Square> get() {
return getCommon(new BoxA());
}
public static void set(List<Square> newList) {
setCommon(new BoxA(), newList);
}
}
它有点hackish但它允许您使用父类来保存一些常用功能。您仍然必须在子类中使用最终方法,但是您在其中所做的只是调用父方法,为它们提供当前类的新实例,以便父方法可以从中推断泛型类型。请注意,getList()
和setList()
不是静态的,以允许它们具有Box的类型参数,并且它们受到保护,因此它们在外部不可见。它们充当私有静态变量(每个扩展类应该具有)的getter setter,以允许访问父级以对属于子级的变量执行常见工作。
get()
和set()
方法使用new BoxA()
(或new BoxB()
)来允许访问静态列表,同时还将type参数传递给父级。由于列表是静态的,因此返回它的实例无关紧要。常用方法有自己的类型参数,而不是类所具有的类型参数;事实上你可以从BoxA内部拨打getCommon(new BoxB())
,所以你的工作就是确保你拨打正确的电话。