提供我的界面如:
public interface Replicateable<T> {
void replicate(T entity);
}
另一个延伸它
// here Identifiable is just another interface
public interface Entity extends Identifiable, Replicateable<Entity> {
//some declarations here
}
在这个链的最后,我想要像
这样的东西public class ConcreteEntity implements Entity {
@Override
public void replicate(ConcreteEntity entity) {
// here goes some logic turning current entity
// to a replica of a passed one
}
}
除了使Entity
接口通用之外,还有哪些方法可以实现这一目标?我宁愿避免这种情况
所以我试过了
1.保持原样,由于replicate()
实现只需要Entity
参数,而不是具体的参数,因此不起作用
2.将Replicateable
权限添加到实体类
public class ConcreteEntity implements Entity, Replicateable<ConcreteEntity> { ... }
给了我'Replicateable' cannot be inherited with different type arguments: 'Entity' and 'ConcreteEntity'
(这似乎可以解释为什么它不起作用)
3.覆盖replicate()
界面中的Entity
(没有任何结果,甚至不确定它是否有意义。)
4.制作一个replicate()
泛型而不是Replicateable
本身(不确定如何使其正确)
非常感谢如何使其成功。
答案 0 :(得分:1)
Entity
必须是通用的,以便编译器知道哪种类型可以传递给replicate
:
Entity<ConcreteEntity> e = ...;
e.replicate(...); // <-- aha. Can only pass a ConcreteEntity (or a subtype of)
使用多态可能更有意义:
interface Replicateable<T> {
T replicate();
}
interface Entity extends Identifiable, Replicateable<Entity> {
// Entity replicate();
}
可以使用复制构造函数实现:
class ConcreteEntity implements Entity {
public ConcreteEntity(ConcreteEntity other) {...}
@Override
public ConcreteEntity replicate() { // <-- uses return type overriding
return new ConcreteEntity(this);
}
}
Entity e1 = new ConcreteEntity();
Entity copy1 = e1.replicate();
ConcreteEntity e2 = new ConcreteEntity();
ConcreteEntity copy2 = e2.replicate();
答案 1 :(得分:1)
由于Generics在Java中的工作方式,您要做的事情要求使Entity变得通用。这是一种奇怪的模式,但不时出现。
public interface Entity<T extends Entity> extends Identifiable, Replicateable<T> {
//some declarations here
}
public class ConcreteEntity implements Entity<ConcreteEntity> {
@Override
public void replicate(ConcreteEntity entity) {
// here goes some logic turning current entity
// to a replica of a passed one
}
}
但是,可能有不同的设计接口的方式,因此不需要这样做。你想用replicate
做什么?
您的评论听起来像您会执行以下操作。
SomeEntity a = new SomeEntity();
// set values on a
SomeEntity b = new SomeEntity();
b.replicate(a);
IF 这就是您要尝试的其他几种方法来实现最终结果
SomeEntity a = new SomeEntity();
// set values on a
SomeEntity b = new SomeEntity(a); // copy constructor
SomeEntity c = a.clone(); // Clone operation
有关根据其他对象的值创建对象的更深入概述,请参阅PrototypePattern。
答案 2 :(得分:1)
如果不Entity
也不通用,那是不可能的。您应该使用F-bounded types:
1989年引入的F-有界量化或递归有界量化允许更精确地键入应用于递归类型的函数。递归类型是包含一个函数的函数,该函数将它用作某个参数或其返回值的类型。
在Java中,F-bounded类型可以用通用接口表示,在您的情况下将如下所示:
public interface Replicateable<T extends Replicateable<T>> {
void replicate(T entity);
}
public interface Entity<T extends Entity<T>> extends Replicateable<T> {
//some declarations here
}
public class ConcreteEntity implements Entity<ConcreteEntity> {
@Override
public void replicate(ConcreteEntity entity) {
// here goes some logic turning current entity
// to a replica of a passed one
}
}
答案 3 :(得分:0)
感谢大家的回答,他们很有见地,帮助我找到合适的解决方案 我最终将可复制的界面重新定义为
public interface Replicateable<T> {
//note the boolean return type here
boolean replicate(T entity);
}
将其保留在实体界面中,而不是将其设为通用
public interface Entity extends Identifiable, Replicateable<Entity> {
//some declarations here
}
允许不重写大量的代码来摆脱原始类型,并且不会破坏实体的泛型方法实现(为什么它在使Entity
本身时被打破是另一个问题,超出了本范围一个。)
方法实现类似于
@Override
public boolean replicate(Entity entity) {
if (entity.getClass() == ConcreteEntity.class) {
// replicating logic
return true;
}
return false;
}
此方法不会创建新对象,而是将现有对象传递给传递给方法的副本,这就是重点(我应该提到它,我为此道歉)。否则我会根据你的一些建议使用Cloneable
所以,总结和概括 - 它要么使Entity
通用,要么使用Cloneable(不是我的情况)或发明一个变通方法,我做了。再次感谢大家。