2010-02-11 43 views
10

重載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

如果你把兩個類實現一個共同的接口,

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

好的建議。 – 2010-02-11 02:37:53

12

Java中泛型的一點是通用類型在運行時被擦除,所以這兩種方法都編譯爲相同的簽名。您將需要具有單獨的方法名稱,或者在運行時檢查列表元素的類型。

+2

的Java並不總是有仿製藥;當它們被添加時,結果字節碼沒有改變。 – Dolph 2010-02-11 01:17:48

+3

是的,這就是使用類型擦除的原因 - 以避免破壞與預代理代碼的向後兼容性。 – danben 2010-02-11 01:27:08

+0

該類型在運行時被擦除。方法重載選擇在編譯時完成。因此,編譯器有足夠的信息來決定,即使是擦除。但是,如果發生此語言更改,則會出現二進制表示和兼容性問題。 – 2010-02-11 23:30:51

7

仿製藥有什麼被稱爲類型擦除 - List<Customer>List<Applicant>屬於同一類型,編譯器只是放置編譯時間上,你可以跟他們做什麼限制。

您可以檢查列表中第一個對象的類型,並根據該內部方法調用(命名不同的)內部方法。

+0

是的,那是我開始看的,檢查課堂和改變行爲。來到SO希望有一個更優雅的解決方案,如果沒有出現,我會繼續沿着這條路線。 – MadMurf 2010-02-11 01:00:39

+0

作爲其他問題,覆蓋選擇在編譯時完成,所以擦除不排除。 – 2010-02-11 23:31:31

-1

進入的方法名前,類的層次結構有點混亂......

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

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

申請人和客戶爲什麼應該是 不同的對象?你能告訴 這些對象之間的關係嗎?要解決此問題

5

一種方法是這樣定義自定義列表類型:

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

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

那麼下面超載將是合法的:

public void processCustomerNumbers(CustomerList custList) 

public void processCustomerNumbers(ApplicantList appList) 

不過,我不知道認爲這將是一個好主意。首先,它將特定的實現類硬連接到應用程序的API中。

更好的方法是爲客戶和申請人定義一個通用接口,允許您使用一種方法處理它們。 (正如在其他答案中詳細描述的那樣)。

0

用數組代替。

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[]{}); 
相關問題