实现在接口中定义的clone返回具体类?

时间:2017-05-01 10:36:02

标签: java oop clone

我正在阅读DesignPatterns('GoF模式')并实现示例MazeGame。在阅读Prototypes时,我遇到了编写克隆方法(cloneIt())的事情。

首先我的结构:

界面:MapSite

AbstractClass:AbstractMapSite

具体Impl:RoomDoorWall

我的计划是在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
    }
}

2 个答案:

答案 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