通用接口以避免转换

时间:2015-02-19 10:00:59

标签: java generics interface

我希望有一个接口根据请求返回不同类型的接口。为了解释这个问题,我使用了一个汽车示例。

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。我应该使用另一个例子。

2 个答案:

答案 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();
    }

}
相关问题