2010-01-27 58 views
1

假设我有:泛型质疑

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 s表示对它们进行操作,如:

Action<Rectangle> 
Action<Blob> 

我想有一个统一的接口,可以适用Action s到Shape的一堆不同的子类。

回答

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); 
} 
+0

+1。在原始代码中,不能保证“形状”是“行动”期望的任何类型。 – 2010-01-27 17:41:24

+0

在这种情况下,我认为泛型只会让事情复杂化。 – jjnguy 2010-01-27 17:46:00

+0

@jjnguy,在这种简单的情况下,似乎没有必要同意泛型。 – 2010-01-27 19:39:33

1

start签名需要S,但你通过它Shape

1

因为动作是为了形状的专业化,而不是任何形状。

3

我不认为你在这种情况下一定需要仿制药。这里是我会做什么:

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

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

然后你就可以通过扩展Shape到方法start()任何类型。

+0

但是假设Action需要在Shape的子类中使用某种方法,例如用于Rectangle的getWidth()方法。在这种情况下,为Shape对象上的矩形运行一个Action需要投射,并且通常不再安全。该怎么办? – Jake 2010-01-27 19:40:04

+0

如果是这种情况,给Shape一个名为'getWidth()'的方法,并在所有子类中正确覆盖它。 – jjnguy 2010-01-27 19:54:28

+0

@Jake请参阅上面的评论。 – jjnguy 2010-01-27 19:55:12

1

对于基本需要,我建议:

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

或者,如果你需要输入他们更强,你可以改变其他:

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