Перегрузка функции Java параметром List
у меня 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 ответов
Если вы делаете оба класса реализуют общий интерфейс,
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());
}
}
дело в дженериках в Java заключается в том, что общие типы стираются во время выполнения, поэтому оба этих метода компилируются с одной и той же сигнатурой. Вам нужно будет иметь отдельные имена методов или проверить тип элементов списка во время выполнения.
дженерики имеют то, что известно как стирания типа - List<Customer>
и List<Applicant>
являются одним и тем же типом, компилятор просто устанавливает ограничения времени компиляции на то, что вы можете с ними сделать.
вы можете проверить тип первого объекта в списке и вызвать (с другим именем) внутренний метод на основе этого.
один из способов обойти эту проблему - определить пользовательские типы списков следующим образом:
class CustomerList extends ArrayList<Customer> {
...
}
class ApplicantList extends ArrayList<Applicant> {
...
}
тогда следующая перегрузка будет законной:
public void processCustomerNumbers(CustomerList custList)
public void processCustomerNumbers(ApplicantList appList)
однако я не думаю, что это была бы хорошая идея. Для начала он подключает определенные классы реализации в API вашего приложения.
лучшим подходом является определение общего интерфейса для клиента и заявителя, который позволяет обрабатывать их с помощью одного processCustomerNumbers
метод. (Как описано в других ответах.)
вместо этого используйте массив.
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[]{});
прежде чем войти в имена методов , иерархия классов немного запутана...
public class Customer{
...
public String getCustomerNumber();
...
}
public class Applicant{
....
private Customer c;
public Customer getCustomer(){ return c; }
...
}
почему заявитель и клиент должны быть разные предметы ? Можешь сказать ... связь между этими объектами ?