1

我正在尝试使用抽象方法创建一个抽象类,它应该能够返回任何类型的列表,其中的项目扩展为SuperBean.

稍后我想创建一个可以将项目添加到该列表的通用类。例子:

class AbstractService<T extends SuperBean> {
    //this is what I'm aiming for
    void add(T item) {
        // "is not applicable for the arguments (T)"
        superBean.getSublist().add(item);
    }
}

abstract class SuperBean {
    abstract List<? extends SuperBean> getSublist();
}

class MyBean1 extends SuperBean {
    List<MyBean2> sublist;

    List<MyBean2> getSublist() {
        return sublist;
    }
}

class MyBean2 extends SuperBean {
    List<MyBean3> sublist;

    List<MyBean3> getSublist() {
            return sublist;
        }
}

问题:我必须如何定义abstract getSublist()类以便我可以添加任何T item实现SuperBean

4

3 回答 3

2

您将需要添加到您的泛型中AbstractService

//        Add S to be T's type parameter         Add <S> to SuperBean here
class AbstractService<S extends SuperBean, T extends SuperBean<S>> {
    // I'm assuming superBean is defined here.
    T superBean;

    //this is what I'm aiming for
    void add(S item) {
        superBean.getSublist().add(item);
    }
}

接下来,您需要创建SuperBean泛型,其子类定义泛型类型参数<T>

abstract class SuperBean<T extends SuperBean> {
    // Now you can define the abstract method properly:
    abstract List<T> getSublist();
}

每个子类都适当地定义了它的泛型类型参数:

class MyBean1 extends SuperBean<MyBean2> {
    List<MyBean2> sublist;

    List<MyBean2> getSublist() {
        return sublist;
    }
}

并且MyBean2定义类似:

class MyBean2 extends SuperBean<MyBean3> {
    List<MyBean3> sublist;

    List<MyBean3> getSublist() {
            return sublist;
    }
}

这允许您按如下方式声明服务:

AbstractService<MyBean2, MyBean1> service1 = new AbstractService<MyBean2, MyBean1>();
AbstractService<MyBean3, MyBean2> service2 = new AbstractService<MyBean3, MyBean2>();
于 2013-08-15T16:36:49.910 回答
1

您的通用参数在这里没有意义。如果你明确泛型类型,你可以看到哪里出错了:

将通用参数添加到您的SuperBean

abstract class SuperBean<T extends SuperBean> {
    abstract List<T> getSublist();
}

并在子类型中明确表示该类型:

class MyBean1 extends SuperBean<MyBean2> {
    List<MyBean2> sublist;

    List<MyBean2> getSublist() {
        return sublist;
    }
}

现在,在您的服务中,您将拥有

class AbstractService<T extends SuperBean<S>> {

    void add(T item) {
        // you cannot do this because the items in the sublist of 
        // your super bean are of the wrong type.
        superBean.getSublist().add(item);
    }
}

另一种方法是将服务设为

class AbstractService<T extends SuperBean<T>>

然后您就可以将项目添加到子列表中,但是您的 bean 类型不正确。例如,MyBean1不扩展SuperBean<MyBean1>,但扩展SuperBean<MyBean2>

于 2013-08-15T16:36:34.457 回答
0

我不确定这是否是您想要的,但不会产生错误。

有两个抽象声明,SuperBean 和 AbstractService(虽然定义了 AbstractService,但我假设它应该是抽象的)。

有三个声明不是抽象的,MyBean{1,2,3}

我定义 awSuperBean 只是为了看看它是否有效。

您粘贴的代码尚未定义 (-grr- 具体的) superBean。因此,我定义了一个名为 awSuperBean 的 superBean 并在(抽象?)add 方法中使用它。

. .

///  testing superbean implementation
//
class awSuperBean<MyBean1> extends SuperBean {
    List<MyBean1>  getSublist() { return new java.util.ArrayList<MyBean1>(); }
}
//
///

class AbstractService<T extends SuperBean> {

/// tests a superbean definition
//
    awSuperBean<T> asuperBean;

    //this is what I'm aiming for
    void add(T item) {
        // "is not applicable for the arguments (T)"

/// use the superbean
        asuperBean.getSublist().add(item);
    }
}

/// every defined SuperBean subtype will need to specify the type 
//  of SuperBean it will produce in it's getSublist call
// 
abstract class SuperBean<getSublist extends SuperBean> {  

/// use the type parameter
//
    abstract List<getSublist> getSublist();
}

我认为您应该只在抽象类中使用参数类型标识符 T。在 superbean 子类型定义中使用声明的类型,而不是混淆 Ts。

于 2013-08-15T18:42:00.737 回答