IHello!
我想克隆一个具有超类型“A”的对象“B”。 在“B”的clone()方法中,我调用super.clone()(“A”的方法)。此方法返回“A”类型,其中包含克隆和设置的字段。
在“B”的clone()方法中,我从super.clone()获取“pre-construct”返回的对象,我想继续克隆它。所以我必须把它变成一个“B”型对象。
编译时没问题,但在运行时崩溃了ClassCastException。
是否可以将对象转换为其子类型? 或者我必须克隆“B”clone()方法中的所有字段(甚至是“A”类字段)吗?
感谢。
答案 0 :(得分:1)
正确的克隆需要使用虚拟方法,该方法在支持克隆的最低级别实现,并且 - 取决于克隆的实现方式 - 被超出添加新字段的每个级别覆盖深度克隆,或被每个派生类,时期覆盖。
如果clone
的所有实现都通过调用super.clone
工作,直到最低级别的类调用object.clone
,然后在派生类型上调用clone
已经转换为基类型将产生该派生类型的对象。不幸的是,super.clone
被打破的信念导致许多人使用复制构造函数而不是调用super.clone
,从而产生了一个不幸的自我实现的预言。
鉴于这种不幸的情况,最好的情况可能是让每个类的父级公开clone
方法可能不会链接到object.clone
,暴露一个protected
拷贝构造函数获取其类型的实例,链到父类的复制构造函数,复制由该公开公开的派生类型添加的任何字段(或映射到属性)或引用不可变对象,并克隆该派生类型的任何字段不公开曝光并引用可变对象。这种方法可行,但是从可克隆类派生的每个类都必须实现自己的虚拟克隆方法的覆盖,即使该方法所做的唯一事情是调用其自己的类的受保护的拷贝构造函数。
如果您的父类具有非虚拟克隆方法,该方法在没有虚拟分派的情况下调用某种构造函数,则无法正确实现任何派生类。
答案 1 :(得分:0)
感谢您的回答,但我找到了解决方案: 我不知道在我的超类的clone()方法中,我必须通过调用super.clone()(来自Object Class的本机clone())来获取我的对象并将其转换为我的类型。 (我做了明确的instanciation MySuperType t = new MySuperType())。
现在,我得到一个MySuperType,我可以在我的子类中向下转换: (MySubClass)sc =(MySubClass)super.clone();
谢谢,所以我会在我的博客www.patate-chaude.fr写一篇文章!