Используя дженерики Java в интерфейсах тот возврат наборы. Лучшая практика? Ловушки?

Я столкнулся с некоторым кодом сегодня, что я нашел сомнительным. Вот упрощенный пример (не реалистичен).

public interface IListable {
    //returns first n items from list
    public ArrayList getFirstNThings(int n);

    //returns last n items from list
    public ArrayList getLastNThings(int n);
}

Затем существует конструктор как так:

public GroceryList implements IListable {
    private ArrayList<GroceryItem> groceries;

    public GroceryList() {
        this.groceries = new ArrayList<GroceryItem>();
    }

    public ArrayList<GroceryItem> getFirstNThings(int n) {
        ArrayList<GroceryItem> firstNThings = new ArrayList<GroceryItem>();
        for (int i=0; i < n; i++) {
            firstNThings.add(this.groceries.get(i));
        }
        return firstNThings
     }

     public ArrayList<GroceryItem> getLastNThings(int n) {
         ArrayList<GroceryItem> lastNThings = new ArrayList<GroceryItem>();
         for (int i=this.groceries.size(); i < this.groceries.size()-n; i--) {
           lastNThings.add(this.groceries.get(i-1);
         }
         return lastNThings;
      }
}

Проигнорируйте любые проблемы реализации, которые можно найти в том (я нашел некоторых также). То, что я достигаю, - то, что интерфейс не использует универсального параметра типа для ArrayList (т.е. ArrayList<?>), но конструктор метода интерфейса делает (т.е. ArrayList <GroceryList>). Другие конструкторы могут возвратить ArrayLists с какими-либо другими параметрами типа, нет?

Так мои вопросы: действительно ли это - проблема? Я должен осуществить рефакторинг что-нибудь? Действительно ли это стоит того? Каково преимущество? С какими проблемами я могу столкнуться, если мне определили метод в интерфейсе, тип возврата которого является необработанным типом, но фактические конструкторы метода возвращают различные параметризованные типы?

5
задан Troy 10 February 2010 в 17:55
поделиться

1 ответ

если оба метода IListable всегда возвращают один и тот же тип, используйте это вместо:

public interface IListable<T> {
  //returns first n items from list
  public ArrayList<T> getFirstNThings(int n);

  //returns last n items from list
  public ArrayList<T> getLastNThings(int n);
}

если это не вариант, попробуйте использовать ? вместо этого. Хотя это в принципе то же самое, это позволяет избежать некрасивых предупреждений.

public interface IListable {
  //returns first n items from list
  public ArrayList<?> getFirstNThings(int n);

  //returns last n items from list
  public ArrayList<?> getLastNThings(int n);
}

Как правило, использование более специфического возвращаемого типа в реализации не является проблемой, чем в супертипе или интерфейсе. Если вы имеете дело с IListable, вам нужно обрабатывать любой тип объекта в возвращаемом списке. Если вы имеете дело с GroceryList, вы ожидаете только GroceryItems. Это справедливо не только для аргументов генетических типов возвращаемых типов, но и для самого возвращаемого типа. Так что если интерфейс определяет List get(), можно реализовать его как ArrayList get().

5
ответ дан 14 December 2019 в 19:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: