在实现类

时间:2016-06-09 14:56:40

标签: java generics

提供我的界面如:

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本身(不确定如何使其正确)

非常感谢如何使其成功。

4 个答案:

答案 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(不是我的情况)或发明一个变通方法,我做了。再次感谢大家。