什么';在这个简单的Java层次结构问题上,我的最佳方法是什么?

什么';在这个简单的Java层次结构问题上,我的最佳方法是什么?,java,generics,subclass,superclass,Java,Generics,Subclass,Superclass,首先,我为问题的标题感到抱歉,但我想不出更好的标题来描述我的问题。请随意更改:) 假设我有一个抽象类Box,它在一些私有变量上实现了一些构造函数、方法和其他东西。然后我有两个子类,比如BoxA和BoxB。这两种方法都实现了额外的功能 现在我有了另一个抽象类Shape和一些子类,如Square和Circle 对于BoxA和BoxB而言,我需要一个Shape对象的列表,但我需要确保只有Square对象进入BoxA的列表,只有Circle对象进入BoxB的列表 对于该列表(在每个框上),我需要一个ge

首先,我为问题的标题感到抱歉,但我想不出更好的标题来描述我的问题。请随意更改:)

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

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

对于
BoxA
BoxB
而言,我需要一个
Shape
对象的列表,但我需要确保只有
Square
对象进入
BoxA
的列表,只有
Circle
对象进入
BoxB
的列表

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

要知道的另一件重要事情是,对于创建的每个框,无论是
BoxA
还是
BoxB
,每个
形状
列表都是完全相同的。假设我创建了一个名为
ls
Square
列表和两个名为
boxA1
boxA2
BoxA
对象列表。无论如何,
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));
    }
}
公共抽象类框{
//私有实例变量
公用信箱(){
//构造器材料
}
//公共实例方法
}
公共类BoxA扩展框{
//私有实例变量
私有静态列表;
公共箱位(){
//构造器材料
}
//公共实例方法
公共静态列表getList(){
List aux=新阵列列表();
对于(正方形s:list.values()){
aux.add(s.clone());//我知道我在用这个克隆做什么,不用担心
}
返回aux;
}
公共静态无效集合列表(列表新建列表){
列表=新数组列表(newList);
}
公共静态空心形状(方形s){
列表。添加(s);
}
公共静态空洞移除形状(方形s){
list.remove(list.indexOf);
}
}
由于该列表需要与该类型的对象相同,因此我将其声明为
static
,并且使用该列表的所有方法也都是
static
。现在,对于
BoxB
来说,关于列表内容,类几乎是相同的。我只会将
正方形
替换为
三角形
,问题就解决了。因此,对于创建的每个
BoxA
对象,列表将只有一个且相同。创建的每个
BoxB
对象都会发生同样的情况,当然列表类型不同

你问我有什么问题?嗯,我不喜欢代码。。。对于
BoxA
BoxB
,基本上重复了
getList()
setList()
addShape()
removeShape()
方法,只是列表将保存的对象的类型不同。我想以某种方式避免所有这些方法的“重复”

我想不出在超级类
框中执行此操作的方法。尝试静态地执行此操作,使用
形状
而不是
正方形
三角形
,将不起作用,因为对于所有
BoxA
BoxB
对象,列表将仅为一个,但对于
Box
的每个子类,我需要它为一个

我怎样才能做得更好


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

你可以尝试以下方法:

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();
抽象保护无效集合列表(列表);
受保护的静态列表getCommon(框){
List aux=新阵列列表();
对于(ts:box.getList()){
辅助添加((T)s.clone());
}
返回aux;
}
受保护的静态void setCommon(框,列表newList){
//如果需要,可以在newList中执行一些操作,作为常用功能
box.setList(newarraylist(newList));
}
}
类BoxA扩展了Box{
私有静态列表;
@凌驾
受保护列表getList(){
退货清单;
}
@凌驾
受保护的无效集合列表(列表){
this.list=列表;
}
公共静态列表get(){
返回getCommon(新的BoxA());
}
公共静态无效集(列表新建列表){
setCommon(new-BoxA(),newList);
}
}
这有点粗糙,但它允许您使用父类来保存一些常见的功能。您仍然需要在子类中拥有final方法,但是您在子类中所做的只是调用父方法,为它们提供当前类的新实例,以便父方法可以从中推断泛型类型。请注意,
getList()
setList()
不是静态的,允许它们具有Box的类型参数,并且它们受到保护,因此在外部不可见。它们充当私有静态变量(每个扩展类都应该有)的getter setter,以允许访问父级,对属于子级的变量执行公共工作

get()
set()
方法使用
new-BoxA()
(或
new-BoxB()
)来允许访问静态列表,同时也将类型参数传递给父级。因为列表是静态的,所以返回它的实例并不重要。常用的方法有自己的类型参数,而不是类的类型参数;实际上,您可以从BoxA内部调用
getCommon(new-BoxB())
,因此您的工作就是