2013-03-01 54 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