Перегрузка Java функционирует со Списком <> параметр

У меня есть 2 класса

public class Customer{
  ...
  public String getCustomerNumber();
  ...
}

public class Applicant{
   ....
   private Customer c;
   public Customer getCustomer(){ return c; }
   ...
}

При дарившем список клиентов или заявителей я хочу функцию, которая выполняет итерации списка и делает что-то с CustomerNumber.

Я попытался перегрузить функцию

public void processCustomerNumbers(List<Customer> custList)
...

public void processCustomerNumbers(List<Applicant> appList)
...

но они рассматриваются как повторяющиеся методы... там хороший способ сделать это вместо того, чтобы просто иметь 2 по-другому именованных функции?

14
задан MadMurf 11 February 2010 в 00:55
поделиться

5 ответов

Если вы заставите оба класса реализовать общий интерфейс,

interface CustomerNumber {
    String getCustomerNumber();
}

public class Customer implements CustomerNumber {
  ...
  public String getCustomerNumber();
  ...
}

public class Applicant implements CustomerNumber {
   ....
   private Customer c;
   public Customer getCustomer() { return c; }
   public String getCustomerNumber() { return getCustomer().getCustomerNumber(); }
   ...
}

тогда вы сможете делать то, что хотите, всего одним методом:

public void processCustomerNumbers(List<? extends CustomerNumber> appList) {
    for (Customer c: appList) {
        processCustomerNumber(c.getCustomerNumber());
    }
}
17
ответ дан 1 December 2019 в 06:53
поделиться

Фишка дженериков в Java в том, что общие типы стираются во время выполнения, поэтому оба этих метода компилируются в одну сигнатуру. Вам нужно будет иметь отдельные имена методов или проверять тип элементов списка во время выполнения.

14
ответ дан 1 December 2019 в 06:53
поделиться

Одним из способов решения этой проблемы является определение типов настраиваемых списков следующим образом:

class CustomerList extends ArrayList<Customer> {
    ...
}

class ApplicantList extends ArrayList<Applicant> {
    ...
}

Тогда следующая перегрузка будет допустимой:

public void processCustomerNumbers(CustomerList custList)

public void processCustomerNumbers(ApplicantList appList)

Однако, Не думаю, что это было бы хорошей идеей. Для начала он встраивает определенные классы реализации в API вашего приложения.

Лучшим подходом является определение общего интерфейса для Заказчика и Заявителя, который позволяет обрабатывать их с помощью одного метода processCustomerNumbers . (Как подробно описано в других ответах.)

5
ответ дан 1 December 2019 в 06:53
поделиться

Прежде чем перейти к именам методов, иерархия классов немного сбивает с толку ...

public class Customer{          
  ...          
  public String getCustomerNumber();          
  ...          
}          

public class Applicant{          
   ....          
   private Customer c;          
   public Customer getCustomer(){ return c; }          
   ...          
}    

Почему заявитель и заказчик должны быть разными объектами? Можете ли вы определить связь между этими объектами?

-1
ответ дан 1 December 2019 в 06:53
поделиться

Generics имеют то, что известно как стирание типов - List и List являются одним и тем же типом, компилятор просто накладывает компилятивные ограничения на то, что вы можете делать с ними.

Вы можете проверить тип первого объекта в списке и вызвать (с другим именем) внутренний метод, основанный на этом.

6
ответ дан 1 December 2019 в 06:53
поделиться
Другие вопросы по тегам:

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