我希望有一个接口根据请求返回不同类型的接口。为了解释这个问题,我使用了一个汽车示例。
public interface ICar{
public ? getCar(String carName);
}
public class Car implements ICar{
public ? getCar(String name){
// Depending on the car name return ICommonCar or IBMW or IAudi...
return new BMW();
Or return new Audi();
...
}
不同的用户类将获得ICar接口,他们可以调用getCar(carName)。例如。 头等舱可以要求:
IBMW mycar = ICar.getCar(BMW);
第二堂课要求:
IAudi myCar = ICar.getCar(Audi);
我当时正在考虑使用Java Generics来解决这个问题,但我认为有些东西是我遗漏的。我的第一种方法是如下所示:
public class Car<T>{
public T getCar(String carName){
public T newCar;
if(carName.equals(BMW)){
T = new BMW(); // Shall I cast it T?
}else if(carName.equals(Audi))
T = new Audi();
}...
return T;
}
上面使用Generics的代码不能编译,但我只是想表明我想要实现的目的。问题似乎很简单,但我发现使用泛型是棘手的。使用泛型可以解决上述问题吗?提前谢谢!
编辑:
请考虑在示例中我并不意味着暗示IBMW&amp; IAudi作为ICar接口的子接口,但我想将ICar作为一个切入点,在该接入点上将对请求执行不同类型的检查。关于班级发起请求。然后实现不相关的接口,如IBMW&amp;将返回作为ICommonCar的子接口的IAudi。我应该使用另一个例子。
答案 0 :(得分:0)
为了实现你所描述的某些事情,你将使客户通过执行自己的演员表做尽可能多的工作。我改变你的班级名字更有意义。致白:
ICarFactory cf = new CarFactory();
// normal way
IAudi audi = ( IAudi )cf.getCar( "audi" );
// your way
IBMW bmw = cf.getCar( "bmw", IBMW.class );
不同之处在于,在前一种情况下,您只需要从ICar
返回getCar
,而在后者中,您需要创建方法 {{1}在变量getCar
中使用generic,然后在返回汽车之前投射到< T extends ICar >
。在所有情况下,这甚至可能都不合法。
同时,在任何一种情况下,你都会得到编译器关于类型的零帮助。
答案 1 :(得分:0)
看起来您正在寻找工厂模式。我尽量避免使用字符串来指定我想要工厂制作的东西 - 枚举很合适。
interface Car {
}
class BMW implements Car {
}
class Audi implements Car {
}
interface MakesCars {
Car makeCar() throws InstantiationException, IllegalAccessException;
}
enum Cars implements MakesCars {
BMW(BMW.class),
Audi(Audi.class);
Class<? extends Car> c;
Cars(Class<? extends Car> c) {
}
@Override
public Car makeCar() throws InstantiationException, IllegalAccessException {
return c.newInstance();
}
}
public void test() throws InstantiationException, IllegalAccessException {
Car bmw = Cars.BMW.makeCar();
}
枚举的Java 8版本更优雅。
enum Cars implements MakesCars {
BMW(BMW::new),
Audi(Audi::new);
final Supplier<Car> supplier;
Cars(Supplier<Car> supplier) {
this.supplier = supplier;
}
@Override
public Car makeCar() {
return supplier.get();
}
}