范围缩小通用的超接口的范围实现类

问题描述:

提供我有这样的接口:范围缩小通用的超接口的范围实现类

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本身(不知道如何作出正确的)

希望任何建议,就如何作出正确选择。

+2

当你说'Entity'实现'Replicateable '时,它意味着'replicate'方法接受任何'Entity'对象。想一想'Comparable ' - 如果你的对象是'Integer',它仍然可以与'Double'相媲美,反之亦然。因此将'Comparable'放在'Number'级别是有意义的。但是,如果您的'replicate'方法只能应用于完全相同类型的对象,则它必须位于该对象的级别。你不能把它放在'Entity'上。 – RealSkeptic

+0

认为使实体通用是最佳实践,但为什么你宁愿避免这种情况? – Zeromus

+1

对我来说,这听起来像[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)...为什么你不想让'Entity'通用? –

谢谢大家对你的答案,他们是有见地的,帮助我拿出一个合适的解决方案。
我最终重新定义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(); 
+0

看起来像你的'replicate()'创建一个新对象,而OP的复制品以某种方式改变当前对象以符合其他对象。这些不是一回事。 – RealSkeptic

+1

@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 
    } 
}