2010-02-11 7 views
10

tengo 2 clasessobrecarga de funciones de Java con la lista <> parámetro

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

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

cuando se le presenta una lista de clientes o solicitantes Quiero una función que itera la lista y hace algo con el Registro del cliente.

he intentado sobrecargar la función

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

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

pero éstos son vistos como métodos duplicados ... ¿hay una buena manera de hacer esto en lugar de tener 2 funciones con nombres diferentes?

Respuesta

14

Si haces ambas clases implementan una interfaz común,

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(); } 
    ... 
} 

entonces usted podría ser capaz de hacer lo que quiera con sólo un único método:

public void processCustomerNumbers(List<? extends CustomerNumber> appList) { 
    for (Customer c: appList) { 
     processCustomerNumber(c.getCustomerNumber()); 
    } 
} 
+0

Buena sugerencia. –

12

Lo que sucede con los genéricos en Java es que los tipos genéricos se borran en tiempo de ejecución, por lo que ambos métodos se compilan con la misma firma. Tendrá que tener nombres de métodos por separado, o verificar el tipo de los elementos de la lista en tiempo de ejecución.

+2

Java no siempre tuvo los genéricos; cuando se agregaron, el bytecode resultante no se modificó. – Dolph

+3

Sí, esa es la razón por la que se utiliza el borrado de tipo: para evitar la compatibilidad con el código pre-genérico. – danben

+0

El tipo se borra en el tiempo de ejecución. La selección de sobrecarga de método se realiza en tiempo de compilación. Por lo tanto, hay suficiente información para que el compilador decida, incluso con borrado. Sin embargo, hay problemas de representación binaria y compatibilidad si este cambio de lenguaje tuviera lugar. –

7

Los genéricos tienen lo que se conoce como tipo borrado-List<Customer> y List<Applicant> son del mismo tipo, el compilador simplemente coloca en tiempo de compilación restricciones sobre lo que puede hacer con ellos.

Puede verificar el tipo del primer objeto en la lista y llamar a un método interno (con un nombre diferente) basado en eso.

+0

Sí, eso fue algo que comencé a mirar, verificando la clase y alterando el comportamiento. Llegué a SO con la esperanza de que hubiera una solución más elegante, si no sale nada, continuaré por esta ruta. – MadMurf

+0

Como otra pregunta, la selección de anulación se realiza en tiempo de compilación, por lo que el borrado no la descarta. –

-1

Antes de entrar en los nombres de los métodos , la jerarquía de clases es poco confuso ...

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

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

¿Por qué el solicitante y el cliente deben ser objetos diferentes? ¿Puedes decirnos la relación entre estos objetos?

5

Una forma de solucionar este problema sería definir tipos de lista personalizada de esta manera:

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

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

A continuación, el siguiente sobrecarga sería legal:

public void processCustomerNumbers(CustomerList custList) 

public void processCustomerNumbers(ApplicantList appList) 

Sin embargo, no lo creo piensa que esta sería una buena idea. Para empezar, conecta las clases particulares de implementación en las API de su aplicación.

Un mejor enfoque es definir una interfaz común para el Cliente y el Solicitante que le permita procesarlos con un método processCustomerNumbers. (Como se describe detalladamente en otras respuestas.)

0

Use matriz en su lugar.

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

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

Cuando intenta llamar a estos métodos con una lista, lista para convertir el array:

List<Customer> customers; 
List<Applicant> applicants; 
... 
processCustomerNumbers(customers.toArray(new Customer[]{}); 
processCustomerNumbers(applicants.toArray(new Applicant[]{}); 
Cuestiones relacionadas