Reputation: 122
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?
Upvotes: 3
Views: 15991
Reputation: 7651
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 Objects or cloning.
Like Josh Bloch says, use interfaces only to define types
.
If your type was defined as:
interface DataObject {
byte[] getData();
Long getId();
Timestamp getCreateDtTm();
}
Your impl might contain:
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.
Upvotes: 3
Reputation: 110046
If you just need to handle copyFrom
differently if the DataObject
it's given is the same type as the object itself, just do something like this:
public class DataObjectImpl implements DataObject {
public void copyFrom(final DataObject source) {
if (source instanceof DataObjectImpl) {
...
}
else {
...
}
}
}
On the other hand, you could do 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) { ... }
}
Upvotes: 4