2009-09-06 5 views
2

У меня есть интерфейс, определенный ниже и реализуемый одним классом MatchedAddressImpl.java generics - one impl class, multiple views

interface MatchedAddress extends HouseHelpData, StreetHelpData, TownHelpData 

public class MatchedAddressDetails implements MatchedAddress 

клиент должен быть обеспечен различные точки зрения (HouseHelpData или StreetHelpData или TownHelpData или MatchedAddress) одного и того же MatchedAddressImpl. Поэтому я предоставил нижеприведенный API для клиентов.

public List<MatchedAddress> matchedAddresses() 
public List<? extends HouseHelpData> houseHelpData() 
public List<? extends StreetHelpData> streetHelpData(); 
public List<TownHelpData> townHelpData(); 

проблема заключается в том, что клиент должен сделать некоторые вещи, как показано ниже, и я прочитал в Effective Java, что возвращаемые типы не должны содержать дикие карты, использование clinet выглядит некрасиво ... Я признателен, если кто-то может помочь я улучшаю API. то, что я хочу, чтобы удалить символы из указанных выше способов ... ТНХ заранее

List<? extends StreetHelpData> streetHelpDataList = details.streetHelpData(); 
+0

Вы думали о пользе не умножать реализующие типов. В общем, один класс делает одно, что вряд ли произойдет, если оно должно быть несколькими вещами. –

ответ

1

Для большинства случаев правильное использование - это просто List<StreetHelpData>. Например, вы могли бы поместить объекты типа StreetHelpDataImpl.

Подстановочные знаки, на мой взгляд, вводят в заблуждение. В принципе, для List<? extends StreetHelpData> это означало бы: «Этот список содержит элементы всего определенного типа, который является подтипом StreetHelpData».

Джокер Пример:

Рассмотрим:

class Animal {} 
class Lion extends Animal {} 
class Tiger extends Animal {} 

В списке List<? extends Animal> содержит либо только Lions (List<Lion>), Tigers только (List<Tiger>), или оба (List<Animal>). Однако в списке List<Animal> могут содержаться все виды Animals - Lions и/или Tigers - в любое время.

(Благодаря Tom Hawtin для его указателей)

+1

'Список ' это 'Список ', поэтому он может содержать как' Lion', так и 'Tiger' в то же время (не знаю, как хорошо они ладят друг с другом). –

+0

Вы правы, спасибо. И нет, я не думаю, что они хорошо ладят ...: P –

1

Зачем вам символы в вашем API, чтобы начать? Избавься от них.

Я предполагаю, что причина, что вы сделали это таким образом это вы пытались сделать следующее в своей реализации:

public List<HouseHelpData> houseHelpData() { 
    List<MatchedAddressDetails> results = new ArrayList<MatchedAddressDetails>(); 
    ... // populate it 
    return results; 
} 

и вы получите ошибку компиляции. Java Generic Tutorial объясняет, почему вышеуказанное является незаконным - в основном это должно помешать вам непреднамеренно добавить в список HouseHelpData реализацию, несовместимую с MatchedAddressDetails, а затем попытаться получить к ней доступ (из списка вниз) как экземпляр MatchedAddressDetails. То, что вы CAN, тем не менее, является:

public List<HouseHelpData> houseHelpData() { 
    List<HouseHelpData> results = new ArrayList<HouseHelpData>(); 
    ... 
    results.add(new MatchedAddressDetails()); 
    ... 
    return results; 
} 

Нет необходимости подстановочные.

Если это не было причиной добавления подстановочных знаков в API, возможно, вы можете уточнить свой вопрос и объяснить, что это было.