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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4045389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:31:38  来源:igfitidea点击:

Using Java generics in an interface to enforce implementation of a method with the implementing type as a parameter

javagenericsinterface

提问by Ioeth

I have an interface like this:

我有一个这样的界面:

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

And a class that implements it:

和一个实现它的类:

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

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

Is there any way that I can enforce the implementation of a "public void copyFrom(DataObjectImpl source)" method in the DataObject interface, using generics or otherwise?

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

回答by ColinD

If you just need to handle copyFromdifferently if the DataObjectit's given is the same type as the object itself, just do something like this:

如果您只需要在给定的对象与对象本身的类型相同的情况下进行copyFrom不同的处理DataObject,请执行以下操作:

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

On the other hand, you coulddo it like this, using a different name for the method taking an implementation type. However, I don't see what good this does.

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

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) { ... }
}

回答by hisdrewness

You could reduce your code by simply doing:

您可以通过简单地执行以下操作来减少代码:

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

or to be more succinct:

或者更简洁:

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

You could use this by calling:

您可以通过调用来使用它:

o.copyFrom(new DataObjectImpl());
o.<DataObjectImpl> copyFrom(new DataObjectImpl());

Using generics, the implementation of DataObject is always going to be erased at runtime. It seems counter intuitive to know about the implementation because you should be programming to the interface. If I were you, I might look into Data Transfer Objectsor cloning.

使用泛型,DataObject 的实现总是会在运行时被删除。了解实现似乎违反直觉,因为您应该对接口进行编程。如果我是你,我可能会研究数据传输对象克隆

Like Josh Bloch says, use interfaces only to define types.

就像乔什·布洛赫 (Josh Bloch) 所说的那样,use interfaces only to define types.

If your type was defined as:

如果您的类型定义为:

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

Your impl might contain:

您的 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
}

The implementation or copy strategy wouldn't matter because any implementation abides by the type contract and can be reduced to this clearly defined type.

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