0

首先,我很抱歉这个问题的标题,但我想不出一个更好的来描述我的问题。随意更改它:)

假设我有这个抽象类Box,它在一些私有变量上实现了几个构造函数、方法和任何东西。然后我有几个子类,比如BoxAand BoxB。这两个都实现了额外的东西。

现在我有了另一个抽象类Shape和一些子类,比如Squareand Circle

对于两者BoxABoxB我需要有一个Shape对象列表,但我需要确保只有Square对象进入BoxA' 列表,并且只有Circle对象进入BoxB' 列表。

对于该列表(在每个框上),我需要一个get()andset()方法以及一个addShape()andremoveShape()方法。

要知道的另一件重要的事情是,对于每个创建的框,无论是BoxA还是BoxB,每个Shape列表都是完全相同的。假设我创建了一个名为 的列表Squarels两个名为and的BoxA对象。无论如何,两者都必须具有相同的列表。boxA1boxA2boxA1boxA2ls

这是我的想法:

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列表内容,课程几乎相同。我只会替换SquareTriangle问题就解决了。因此,对于创建的每个BoxA对象,列表将只有一个且相同。每个BoxB创建的对象都会发生同样的情况,但当然是使用不同类型的列表。

那么,你问我的问题是什么?好吧,我不喜欢代码... getList()setList()addShape()removeShape()方法基本上是重复的BoxABoxB,只是列表将包含的对象的类型不同。我想以某种方式避免所有这些方法“重复”。

我想不出在超类中做这件事的方法Box。尝试静态地执行它,使用Shape而不是Squareor Triangle,将不起作用,因为列表对于所有对象BoxABoxB对象来说只有一个,我需要它只是一个,但对于Box.

我怎样才能以不同的方式更好地做到这一点?

PS:我无法描述我的真实例子,因为我不知道我正在做的事情的正确英文单词,所以我只是使用了一个盒子和形状的例子,但它基本上是一样的。

4

1 回答 1

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);
    }
}

这有点骇人听闻,但它允许您使用父类来保存一些常用功能。您仍然必须在子类中拥有最终方法,但您在它们中所做的只是调用父方法,为它们提供当前类的新实例,以便父方法可以从中推断出泛型类型。请注意,getList()andsetList()不是静态的,不允许它们具有 Box 的类型参数,并且它们受到保护,因此它们在外部不可见。它们充当私有静态变量(每个扩展类都应具有)的 getter setter,以允许访问父级以对属于子级的变量执行共同工作。

The get() and set() method use new BoxA() (or new BoxB()) to allow access to the static list, while also passing the type parameter to the parent. Since the list is static it doesn't matter what instance returns it. The common methods have they're own type parameter which is not the one the class have; you could in fact call getCommon(new BoxB()) from inside BoxA, so it will be your job to ensure that you call the right one.

于 2010-05-28T17:18:39.087 回答