范围缩小通用的超接口的范围实现类
提供我有这样的接口:范围缩小通用的超接口的范围实现类
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
INT rface通用?我宁愿避免这种情况。
所以对于我试图
1.保持原样,不工作,因为replicate()
实现需要准确的Entity
参数,而不是具体的一个
2.添加Replicateable
权实体类
public class ConcreteEntity implements Entity, Replicateable<ConcreteEntity> { ... }
哪给了我'Replicateable' cannot be inherited with different type arguments: 'Entity' and 'ConcreteEntity'
(这似乎是可以理解的为什么它没有工作)。
3.覆盖Entity
接口中的replicate()
(没有结果,甚至不确定它是否有意义)。
4.一个replicate()
通用的,而不是Replicateable
本身(不知道如何作出正确的)
希望任何建议,就如何作出正确选择。
谢谢大家对你的答案,他们是有见地的,帮助我拿出一个合适的解决方案。
我最终重新定义replicateable接口
public interface Replicateable<T> {
//note the boolean return type here
boolean replicate(T entity);
}
离开它,因为它是在实体界面,使其不致通用
public interface Entity extends Identifiable, Replicateable<Entity> {
//some declarations here
}
允许不重写大量代码,以摆脱原始类型并且不会破坏实体的通用方法实现(为什么它在制作时被破坏本身是另一个超出此范围的问题。)
方法实现看起来像
@Override
public boolean replicate(Entity entity) {
if (entity.getClass() == ConcreteEntity.class) {
// replicating logic
return true;
}
return false;
}
此方法不会创建一个新的对象,将现有的对象传递给传递给该方法的副本,这就是要点(我应该提及它,我的道歉)。否则,我会使用Cloneable,根据您的一些建议。
因此,总结和概括 - 它可以是Entity
通用或使用可复制(不是我的情况)或创造一个解决方法,我做了。再次感谢大家。
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();
看起来像你的'replicate()'创建一个新对象,而OP的复制品以某种方式改变当前对象以符合其他对象。这些不是一回事。 – RealSkeptic
@RealSkeptic我知道,但它可能同样适用于OP想要做的事情。值得一提的是,因为他们不希望“Entity”是通用的。 –
什么你正在尝试做的,需要做实体一般是由于仿制药在Java中的工作方式。这是一个奇怪的模式,但它不时出现。
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为基于价值创造的对象进行更深入的概述的其他物体。
如果没有使Entity
也是通用的,这是不可能的。您应该使用F-bounded types:
F-界定量或递归界量化,于1989年推出,允许那些在递归类型应用的功能更精确的输入。递归类型是一个包含一个函数的函数,该函数将其用作某个参数或其返回值的类型。
在Java中,F-界类型可以用一个通用的接口,而你的情况会是如下表示:
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
}
}
当你说'Entity'实现'Replicateable'时,它意味着'replicate'方法接受任何'Entity'对象。想一想'Comparable ' - 如果你的对象是'Integer',它仍然可以与'Double'相媲美,反之亦然。因此将'Comparable'放在'Number'级别是有意义的。但是,如果您的'replicate'方法只能应用于完全相同类型的对象,则它必须位于该对象的级别。你不能把它放在'Entity'上。 –
RealSkeptic
认为使实体通用是最佳实践,但为什么你宁愿避免这种情况? – Zeromus
对我来说,这听起来像[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)...为什么你不想让'Entity'通用? –