2010-02-11 26 views
10

tôi có 2 lớpquá tải Java chức năng với List <> tham số

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

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

Khi trình bày với một danh sách khách hàng hoặc người nộp đơn tôi muốn có một chức năng mà lặp danh sách và làm điều gì đó với CustomerNumber.

tôi đã cố gắng quá tải chức năng

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

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

nhưng những được coi là phương pháp trùng lặp ... là có một cách tốt đẹp để làm điều này thay vì chỉ có 2 cách khác nhau đặt tên chức năng?

Trả lời

14

Nếu bạn thực hiện tất cả các lớp học thực hiện một giao diện chung,

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

sau đó bạn có thể có thể làm những gì bạn muốn chỉ với một phương pháp duy nhất:

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

Đề xuất tốt. –

12

Điều về Generics trong Java là các kiểu generic bị xóa khi chạy, vì vậy cả hai phương thức này đều được biên dịch cho cùng một chữ ký. Bạn sẽ cần phải có tên phương thức riêng biệt hoặc kiểm tra loại phần tử danh sách khi chạy.

+2

Java đã không luôn luôn có Generics; khi chúng được thêm vào, bytecode kết quả không thay đổi. – Dolph

+3

Vâng, đó là lý do để sử dụng loại tẩy xoá - để tránh phá vỡ tính tương thích ngược với mã tiền Generics. – danben

+0

Loại được xóa khi chạy. Phương pháp lựa chọn quá tải được thực hiện tại thời gian biên dịch. Do đó, có đủ thông tin để trình biên dịch quyết định, ngay cả khi xóa. Tuy nhiên, có các vấn đề tương thích nhị phân và tương thích nếu thay đổi ngôn ngữ này xảy ra. –

7

Generics có gì được gọi là loại chô bôi-List<Customer>List<Applicant> là cùng loại, trình biên dịch chỉ đặt thời gian biên dịch hạn chế về những gì bạn có thể làm với họ.

Bạn có thể kiểm tra loại đối tượng đầu tiên trong danh sách và gọi phương thức nội bộ (được đặt tên khác) dựa trên đó.

+0

Vâng, đó là điều tôi bắt đầu xem xét, kiểm tra lớp và thay đổi hành vi. Đến SO hy vọng có một giải pháp thanh lịch hơn, nếu không có gì đi lên tôi sẽ tiếp tục xuống tuyến đường này. – MadMurf

+0

Như câu hỏi khác, ghi đè lựa chọn được thực hiện tại thời gian biên dịch để xóa không loại trừ nó ra. –

-1

Trước khi đi vào các tên phương pháp , hệ thống phân cấp lớp hơi khó hiểu ...

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

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

Tại sao người nộp đơn và Khách hàng phải là các đối tượng khác nhau? Bạn có thể cho biết mối quan hệ giữa các đối tượng này không?

5

Một cách để workaround vấn đề này sẽ được xác định loại danh sách tùy chỉnh như thế này:

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

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

Sau đó, quá tải sau sẽ là hợp pháp:

public void processCustomerNumbers(CustomerList custList) 

public void processCustomerNumbers(ApplicantList appList) 

Tuy nhiên, tôi không nghĩ rằng đây sẽ là một ý tưởng hay. Để bắt đầu, nó sẽ cứng các lớp triển khai cụ thể vào các API của ứng dụng của bạn.

Cách tiếp cận tốt hơn là xác định giao diện chung cho Khách hàng và Người đăng ký cho phép bạn xử lý chúng bằng một phương thức processCustomerNumbers. (Như được mô tả theo chiều dài trong các câu trả lời khác.)

0

Sử dụng mảng thay thế.

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

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

Khi bạn cố gắng để gọi các phương pháp này với một danh sách, chuyển đổi danh sách để mảng:

List<Customer> customers; 
List<Applicant> applicants; 
... 
processCustomerNumbers(customers.toArray(new Customer[]{}); 
processCustomerNumbers(applicants.toArray(new Applicant[]{}); 
Các vấn đề liên quan