由另一个泛型限定的泛型类型

时间:2011-01-19 01:43:02

标签: java generics bounded-types

假设我有这个:

interface Shape {}
interface Square extends Shape {}
interface Circle extends Shape {}

interface ShapeBuilder<S extends Shape> {}

我想要这样的事情:

class ShapeBuilderFactory<SB extends ShapeBuilder> {
    SB<Square> getSquareBuilder(){...}
    SB<Circle> getCircleBuilder(){...}
}

此代码无法编译(因为ShapeBuilder是原始类型),但我希望您理解这个想法。 在java中可以做这样的事吗?怎么样?

(真正的问题不在于形状构建器和工厂,为简单起见我使用了这个例子)

修改(更多背景信息)

我有不同类型的建设者:

interface RegularShapeBuilder<S extends Shape> extends ShapeBuilder<S> {}
interface FunnyShapeBuilder<S extends Shape> extends ShapeBuilder<S> {}

class RegularSquareBuilder extends RegularShapeBuilder<Square> {}
class FunnySquareBuilder extends FunnyShapeBuilder<Square> {}
class RegularCircleBuilder extends RegularShapeBuilder<Circle> {}
class FunnyCircleBuilder extends FunnyShapeBuilder<Circle> {}

我希望工厂做这样的事情:

ShapeBuilderFactory<FunnyShapeBuilder> funnyShapeBuilderFactory = ...;
FunnyShapeBuilder<Square> funnySquareBuilder = funnyShapeBuilderFactory.getSquareBuilder();

3 个答案:

答案 0 :(得分:2)

class ShapeBuilderFactory<S extends Shape, SB extends ShapeBuilder<S>> {

虽然您可能会考虑是否需要它是通用的。

答案 1 :(得分:1)

我不确定你为什么不会这样做:

class ShapeBuilderFactory {
    ShapeBuilder<Square> getSquareBuilder(){...}
    ShapeBuilder<Circle> getCircleBuilder(){...}
}

修改

因此,如果您的工厂中必须拥有ShapeBuilder子类型,则需要声明其中的每一个:

class ShapeBuilderFactory<SqB extends ShapeBuilder<Square>, 
                          CiB extends ShapeBuilder<Circle>> {
    SqB getSquareBuilder(){...}
    CiB getCircleBuilder(){...}
}

所以你必须将其声明为:

ShapeBuilderFactory<FunnySquareBuilder, FunnyCircleBuilder> funnyShapeBuilder = ...

但你可以说

FunnyShapeBuilder<Square> funnySquareBuilder = funnyShapeBuilderFactory.getSquareBuilder();

你遇到的问题是ShapeBuilder的实现只能创建一种形状。这就是你宣布它的方式。

如果这是我的代码,我将使用我最初编写的ShapeBuilderFactory定义,并使用有趣或常规的构建器实例化它。是不是让这些接口实际使用它们?

答案 2 :(得分:0)

将泛型放在工厂类上,执行以下操作:

interface Shape {}
interface Square extends Shape {}
interface Circle extends Shape {}

interface ShapeBuilder<S extends Shape> {}

class ShapeBuilderFactory {
    ShapeBuilder<Square> getSquareBuilder(){...}
    ShapeBuilder<Circle> getCircleBuilder(){...}
}