假设我有:
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
}
换句话说,将来我可能会对Shape
和Action
的子类进行操作,如:
Action<Rectangle>
Action<Blob>
我希望有一个统一的界面,可以将Action
应用于Shape
的一堆不同的子类。
答案 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);
}