在接口中使用Java泛型来强制实现具有实现类型作为参数的方法

时间:2010-10-28 17:11:24

标签: java generics interface

我有这样的界面:

public interface DataObject {
    ...
    public void copyFrom(DataObject source);
    ...
}

实现它的类:

public class DataObjectImpl implements DataObject {
    ...
    @Override
    public void copyFrom(final DataObject source) {...}

    public void copyFrom(final DataObjectImpl source) {...}
    ...
}

有没有什么方法可以使用泛型或其他方法在DataObject接口中强制执行“public void copyFrom(DataObjectImpl source)”方法?

2 个答案:

答案 0 :(得分:4)

如果你只需要copyFrom给出的DataObject与对象本身的类型相同,那么只需执行以下操作:

public class DataObjectImpl implements DataObject {
  public void copyFrom(final DataObject source) {
    if (source instanceof DataObjectImpl) {
      ...
    }
    else {
      ...
    }
  }
}

另一方面,可以这样做,对于采用实现类型的方法使用不同的名称。但是,我不知道这有什么好处。

public interface DataObject<T extends DataObject<T>> {
  public void copyFrom(DataObject source);
  public void copyFromImpl(T source);
}

public class DataObjectImpl implements DataObject<DataObjectImpl> {
  public void copyFrom(final DataObject source) { ... }
  public void copyFromImpl(final DataObjectImpl source) { ... }
}

答案 1 :(得分:3)

您只需执行以下操作即可减少代码:

interface DataObject {
   public <T> void copyFrom(T impl);
}

或者更简洁:

interface DataObject {
   public <T extends DataObject> void copyFrom(T impl);
}

你可以通过调用:

来使用它
o.copyFrom(new DataObjectImpl());
o.<DataObjectImpl> copyFrom(new DataObjectImpl());

使用泛型,DataObject的实现总是会在运行时被删除。了解实现似乎反直觉,因为您应该对接口进行编程。如果我是你,我可能会调查Data Transfer Objectscloning

像Josh Bloch所说,use interfaces only to define types

如果您的类型定义为:

interface DataObject {
   byte[] getData();
   Long getId();
   Timestamp getCreateDtTm();
}

您的impl可能包含:

class DataObjectImpl implements DataObject {
   // member vars
   public DataObjectImpl(DataObject dataObject) {
      this.data = dataObject.getData();
      this.id = dataObject.getId();
      this.createDtTm = dataObject.getCreateDtTm();
   }
   //getters and setters
}

实施或复制策略无关紧要,因为任何实施都遵守类型合同,并且可以简化为明确定义的类型。