2013-03-01 57 views
0

我正在編寫一個用於克隆對象的複製構造函數。當一個班級有一個參考對象時,其他班級進一步接受這個對象。如何避免複製構造函數中的instanceof繼承java clasess

class Person 
{ 
    String name; 
    Address address; 
} 

class HomeAdress extends Address 
{ 
} 
class OfficeAdress extends Address 
{ 
} 

現在在Person的複製構造函數中,要決定要將哪個Address對象進行注入,我必須使用instanceof。

public Person(Person p) 
{ 
    name = p.name; 
    if(p.address instanceof HomeAddress) 
    { 
     address = new HomeAddress((HomeAddress) address); 
    }else if(p.address instanceof OfficeAddress) 
    { 
     address = new OfficeAddress((OfficeAddress) address); 
    } 
} 

因此,這種基本問題與新型地址添加到模型時相同。我將不得不在Person拷貝構造函數中添加一個相同的檢查。有沒有辦法避免instanceof檢查來實例化正確的地址對象。我可以使用refelction從代碼中避免instanceof嗎?

+1

不是你的實際問題的答案,但你應該使用'address = new HomeAddress((HomeAddress)p.address);'(你忘了'p.'兩次)。 – jlordo 2013-03-01 14:11:38

+1

我有類似的情況,並在鏈接中解決。 http://stackoverflow.com/questions/13450953/create-an-instance-within-abstract-class-using-reflection。希望這有助於公共類派生擴展基本公共類靜態無效的主要(字符串...參數){ System.out.println(new Derived()。createInstance()); } } 抽象類基地{ 公共基地的createInstance(){ 使用反射 嘗試{//返回 的getClass()asSubclass(Base.class).newInstance(); (異常e){ throw new AssertionError(e); } } } – 2013-03-01 14:14:48

+1

最好的方法是避免複製構造函數。我從來沒有寫過一個Java的十六年。你爲什麼認爲你需要一個? – EJP 2013-03-01 22:26:11

回答

-2

首先,我想這是一個錯字:

address = new HomeAddress((HomeAddress) p.address); 

二,而不是鑄造的對象,你可以定義一個copy()方法地址類,(可能是)摘要:

abstract class Address { 
    abstract Address copy(); 
} 

你實現該方法在每個地址的子類,那麼你可以調用它的人的構造函數:

public Person(Person p) 
{ 
    name = new String(p.name); 
    address = p.address.copy(); 
} 
+1

你爲什麼要調用'new String(p.name)'?爲什麼不復制字符串引用?畢竟,字符串是不可變的。 – 2013-03-01 14:47:35

+0

@JonSkeet Kunal想製作Person的副本,但他只克隆了Person和Address,然而沒有克隆name。當然,使用相同的「名稱」不會有什麼區別,但我只是想製作一個「真實」的副本,就是這樣。而且你是正確的,通常不需要複製一個字符串。 – shuangwhywhy 2013-03-01 15:00:51

+3

這不僅沒有必要 - 它是有害的,因爲它需要處理器和CPU。如果以* no *解釋的答案來做這件事,很容易導致OP一味的抄襲它,並且陷入壞習慣。理解克隆某些東西時很重要,可以爲不可變類型執行簡單的引用副本。 – 2013-03-01 15:13:36

8

您應該將複製地址的責任委託給Address類。無論您是否實施Cloneable,請在中輸入clone()方法,然後您可以(如果您需要自定義處理)在每個特定的Address子類中覆蓋它。然後在你的Person拷貝構造函數,你只需要:

this.address = p.address.clone(); 
+0

http://stackoverflow.com/questions/5092540/accessing-clone-from-java-lang-object http://stackoverflow.com/questions/2427883/clone-vs-copy-constructor-which-is-recommended -in-java 也很少有其他地方克隆不被新紀元。所以我決定用複製構造函數。這就是爲什麼我要求克隆以外的解決方案。 感謝您的幫助。 – kunal 2013-03-01 14:15:18

+0

@kunal:那麼你可以使用'Person'的複製構造函數,但仍然可以使'Address'可複製。看起來你已經看到了克隆的缺點,但沒有考慮到任何優勢*,或者減少了缺點。 – 2013-03-01 14:23:49

+2

@kunal:當你不同意我的答案時,我很好奇你爲什麼接受了與我的答案完全相同的答案。 (可克隆的概念與是否實際實現'Cloneable'接口並使用'java.lang.Object'中的'clone()'是分開的。) – 2013-03-01 14:38:16