泛型问题

时间:2010-01-27 17:35:28

标签: java generics

假设我有:

public interface Action<S extends Shape> {
  public void start( S shape );
}

为什么我会得到以下内容?

public <S extends Shape> void performAction( Action<S> action, Shape shape ) {
  action.start(shape);  // error: cannot supply Shape
}

换句话说,将来我可能会对ShapeAction的子类进行操作,如:

Action<Rectangle>
Action<Blob>

我希望有一个统一的界面,可以将Action应用于Shape的一堆不同的子类。

5 个答案:

答案 0 :(得分:5)

我认为你需要这样的东西:

public <S extends Shape> void performAction(Action<S> action, S shape) {
     action.start(shape);
}

然而,在这种情况下,如果您感兴趣的只是Shape及其子类,则不清楚使用泛型有什么价值。下面的代码可以完成同样的事情。

public interface Action {
    public void start(Shape someShape);
}

public void performAction(Action action, Shape someShape) {
    action.start(someShape); 
}

但是,如果Action类是完全通用的,并且可以与Shape及其子类以外的对象一起使用,那么您可以执行以下操作:

public interface Action<S> {
    public void start(S target);
}

public <S> void performAction(Action<S> action, S target) {
    action.start(target);
}

答案 1 :(得分:3)

在这种情况下,我认为你不一定需要泛型。这就是我要做的事情:

public interface Action {
  public void start( Shape someShape );
}

public void performAction( Action action, Shape someShape ) {
  action.start(someShape); 
}

然后,您可以将Shape扩展的任何类型传递到方法start()

答案 2 :(得分:1)

start的签名需要S,但您传递Shape

答案 3 :(得分:1)

因为动作是针对形状的特化,而不是任何形状。

答案 4 :(得分:1)

基本需要,我建议:

public interface Action {
  public void start(Shape shape );
}

或者如果您需要更强大地键入它们,您可以更改另一个:

public <S extends Shape> void performAction( Action<S> action, S shape ) {
  action.start(shape); 
}