Перегрузка Java-функции параметром List <> - PullRequest
13 голосов
/ 11 февраля 2010

у меня 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 функции с разными именами?

Ответы [ 6 ]

17 голосов
/ 11 февраля 2010

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

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());
    }
}
14 голосов
/ 11 февраля 2010

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

6 голосов
/ 11 февраля 2010

Обобщения имеют так называемый тип стирания . - List<Customer> и List<Applicant> относятся к одному типу, компилятор просто накладывает ограничения на время компиляции на то, что вы можете с ними делать.

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

5 голосов
/ 11 февраля 2010

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

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

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

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

public void processCustomerNumbers(CustomerList custList)

public void processCustomerNumbers(ApplicantList appList)

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

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

0 голосов
/ 31 июля 2017

Вместо этого используйте массив.

public void processCustomerNumbers(Customer[] custList)
...

public void processCustomerNumbers(Applicant[] appList)
...

Когда вы пытаетесь вызвать эти методы со списком, преобразуйте список в массив:

List<Customer> customers;
List<Applicant> applicants;
...
processCustomerNumbers(customers.toArray(new Customer[]{});
processCustomerNumbers(applicants.toArray(new Applicant[]{});
0 голосов
/ 11 февраля 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...