2015-02-19 3 views
0

Я хочу иметь интерфейс, который возвращает разные типы интерфейсов на основе запрошенных. Чтобы объяснить проблему, я использовал пример автомобиля.Общий интерфейс, чтобы избежать литья

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 сложным. Можно ли решить эту проблему с помощью Generics? Заранее спасибо!

EDIT:

Пожалуйста, обратите внимание, что в примере, который я не имел в виду, что IBMW & IAudi в качестве дочерних интерфейсов интерфейса ИКАР, но, скорее, я имел в виду, чтобы иметь ИКАР в качестве отправной точки, где различные типы проверки будут выполняться по запросу & по инициирующему классу запросу. Тогда будет возвращена реализация несвязанных интерфейсов, таких как IBMW & IAudi, которые являются дочерними интерфейсами ICommonCar. Я должен был использовать другой пример.

+0

Я думаю, вы должны объяснить больше, что вы хотите сделать, или, по крайней мере, в каком случае вы хотите применить это. – TheRedFox

+0

Дженерики вообще не работают так, как вы ожидаете их здесь. прежде чем я помогу в ответе, я предпочел бы для большего пользы, что вы прочитали учебник по java generics http://docs.oracle.com/javase/tutorial/java/generics/ – Jatin

+0

@ TheRedFox. Все, что я хочу, это иметь метод с анонимным типом возврата. Метод, который может возвратиться, например. IBMW или IAudi динамически основаны.Если я объявлю возвращаемый тип метода getCar как IBMW, я не смогу вернуть IAudi & vise versa. – Habeshaw

ответ

0

Чтобы достичь чего-то, что вы описываете, вы собираетесь сделать так, чтобы клиент выполнял свою работу, выполняя собственный бросок. Я изменяю имена классов, чтобы иметь больше смысла. Для йота:

ICarFactory cf = new CarFactory(); 
// normal way 
IAudi audi = (IAudi)cf.getCar("audi"); 
// your way 
IBMW bmw = cf.getCar("bmw", IBMW.class); 

Разницы в том, что в первом случае, вам нужно только вернуть ICar из getCar, в то время как в последнем случае, вам нужно сделать метод getCar родовым в переменной < T extends ICar >, а затем бросить в T перед возвратом вашего автомобиля. Это может быть даже не законным во всех случаях.

Тем временем вы получаете нулевую помощь от компилятора относительно типов в любом случае.

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

} 
+0

Я думаю, что OP хочет, чтобы возвращаемый тип 'makeCar' каким-то образом менялся в отношении того, какой автомобиль был вызван. –

+0

@JudgeMental - Это не то, как я читаю вопрос - возможно, это со временем станет более ясным. – OldCurmudgeon

Смежные вопросы