含抽象clone()方法的父类克隆:无法调用Item的clone方法且不想修改该类
解决无法调用抽象Item类clone()方法且不修改原类的问题
嘿,我完全懂你现在的困扰——想克隆Item的子类实例,但没法直接调用抽象的clone()方法,还不能改Item本身,对吧?别慌,咱们有好几种可行的方案,而且都不用动原有的Item类:
方案1:在子类Tool中实现抽象clone()方法
既然Item已经定义了抽象的clone()方法,那你只需要在Tool类里把这个方法落地就行,完全不用碰父类的代码。举个例子:
class Tool extends Item { // 假设Tool有自己的属性,比如耐用度durability private int durability; public Tool(String name, int durability) { super(name); this.durability = durability; } @Override public Item clone() { try { // 利用Object的clone()做浅拷贝,因为Item实现了Cloneable接口,所以这步是合法的 Tool clonedTool = (Tool) super.clone(); // 复制子类自己的属性,如果是引用类型这里要做深拷贝,基本类型直接赋值就行 clonedTool.durability = this.durability; return clonedTool; } catch (CloneNotSupportedException e) { // 因为Item已经实现了Cloneable,理论上不会走到这里,还是做个异常处理更稳妥 throw new RuntimeException("克隆Tool实例失败", e); } } }
这里的关键是:虽然Item的clone()是抽象的,但它实现了Cloneable接口,所以子类可以调用super.clone()来复制父类的所有字段(包括private的stackable),然后再处理子类自己的属性,完美避开修改Item类的需求。
方案2:用拷贝构造函数/工厂方法替代clone()机制
如果你觉得Java的clone()机制太别扭,也可以在子类里写拷贝构造函数或者工厂方法来创建实例副本,同样不用动Item类:
拷贝构造函数示例
class Tool extends Item { private int durability; public Tool(String name, int durability) { super(name); this.durability = durability; } // 拷贝构造函数,接收一个原Tool实例 public Tool(Tool original) { super(original.name); // 这里要注意:Item的stackable是private属性,子类直接访问不到 // 所以还是得借助super.clone()来复制父类的私有字段,或者如果允许的话给Item加getter,但你不想改Item,所以结合clone()更靠谱 try { super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException("父类克隆失败", e); } this.durability = original.durability; } @Override public Item clone() { return new Tool(this); } }
不过这个方案有个小坑:Item的stackable是私有属性,子类没法直接访问赋值,所以还是得依赖super.clone()来复制父类的所有字段,本质上还是和第一种方案结合使用更顺畅。
为什么你没法直接调用Item的clone()?
其实原因很简单:Item是抽象类,你不能直接实例化它;而且它的clone()是抽象方法,必须由子类来实现具体逻辑。所以核心就是在子类里完成这个方法的实现,完全不需要修改父类。
总结一下:最省心且符合你需求的办法就是方案1——在Tool子类中正确实现clone()方法,利用super.clone()复制父类字段,再处理子类自己的属性。
内容的提问来源于stack exchange,提问作者ABHAY KUMAR
相关产品推荐
相关产品推荐

