我正在阅读DesignPatterns('GoF模式')并实现示例MazeGame
。在阅读Prototypes时,我遇到了编写克隆方法(cloneIt()
)的事情。
首先我的结构:
界面:MapSite
AbstractClass:AbstractMapSite
具体Impl:Room
,Door
,Wall
我的计划是在cloneIt
中定义MapSite
并提供默认实现(只需调用Object.clone()
),这可以在具体类中覆盖。现在,cloneIt()
方法始终返回接口类型MapSite
。
有没有办法'强制'Java返回具体的类类型(Room, Door, Wall
),尽管使用了抽象类中的方法?这可以避免强制转换。
我知道接口的优点及其使用原因:)
解决方案
正如@ philipp-wendler和@davidxxx建议的那样,我最终使用了泛型。如果Object.clone()
的浅表副本有问题,我会在具体类中覆盖cloneIt()
。
public interface MapSite<T> extends Serializable {
T cloneIt();
}
...
public abstract class AbstractMapSite<T> implements MapSite<T> {
public T cloneIt() {
try {
return (T) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
...
public class Wall extends AbstractMapSite<Wall> {
public Wall cloneIt(){
// special code here
}
}
答案 0 :(得分:1)
我的计划是在MapSite中定义cloneIt并提供默认值 实现(简单地调用Object.clone()),可以覆盖它 在具体课程中。
请注意:Object.clone()
的默认实现会对克隆对象进行浅层复制,如果您不想查看Cloneable
,还应该实现CloneNotSupportedException
界面被抛出。
因此,您应该覆盖clone()
和cloneIt()
。这很令人困惑,因为单一方法就足够了。只需保留cloneIt()
并忘记笨拙的clone()
方法。
有没有办法强迫&#39; Java返回具体的类类型 (房间,门,墙)尽管抽象类的方法是 用过的?这可以避免铸件。
使用Generics是的,你可以做到。
例如:
public interface MapSite<T>{
T cloneIt();
}
public abstract class AbstractMapSite<T> implements MapSite<T>{
...
}
public class Wall extends AbstractMapSite<Wall>{
public Wall cloneIt(){
...
}
}
答案 1 :(得分:1)
您需要一个递归泛型类型:
public interface MapSite<T extends MapSite<T>> {
T cloneIt();
}
public abstract class AbstractMapSite<T extends AbstractMapSite<T>> implements MapSite<T> {
}
public class Room extends AbstractMapSite<Room> {
public Room cloneIt() { ... }
}
此类型强制MapSite
的非抽象子类将T
声明为自己的类型,从而保证cloneIt
的正确返回类型。
如果您拨打cloneIt
并使用未经检查的强制转换为clone()
,您也可以在抽象类中实现T
。