创建仅限于自己的类的通用接口

时间:2013-08-26 11:51:03

标签: java generics interface

我想为这两个类创建一个通用接口,但我不确定如何以正确的方式指定泛型。

public class ThingA implements Thing {
    public ThingA createCopy(ThingA original);
}

public class ThingB implements Thing {
    public ThingB createCopy(ThingB original);
}

我试过这个。

public interface Thing<V extends Thing<V>> {
    public V createCopy(V original);

}

但是我仍然可以做这样的事情,这是不允许的。

public class ThingB implements Thing<ThingA> {
    public ThingA createCopy(ThingA original);
}

4 个答案:

答案 0 :(得分:6)

没有this关键字泛型(也没有方法参数和返回值声明),因此您无法完全按照自己的意愿行事。

换句话说,接口将允许确保类中的所有方法都使用一致的类型,但不能引用类类型本身。

答案 1 :(得分:1)

这是不可能的。并不是Generics的用途。泛型用于类型安全,即避免强制转换。如果有人创建了一个以某种方式实现ThingB的类Thing<ThingA>,那就太好了。它完全是类型安全的。你为什么在乎?它如何阻碍你的工作?

答案 2 :(得分:0)

您在寻找

吗?
public interface Thing<V> {
    public V createCopy(V original);
}

?如果没有,你能否更详细地解释一下“为两个类创建一个通用接口”对你意味着什么?

答案 3 :(得分:0)

如果您可以自由使用扩展而不是实现,那么您可以这样做:

public interface Thing { ... }
public abstract class Copyable {
    public final Copyable copy() {
        Copyable clone = createCopy();
        if (clone.getClass() != getClass())
            throw new RuntimeException("Copy has wrong type!");
        return clone;
    }
    protected abstract Copyable createCopy();
}

然后使用它:

public class Test extends Copyable implements Thing {
    public String content = null;

    @Override
    public Copyable createCopy() {
        Test clone = new Test();
        clone.content = this.content;
        return clone;
    }
}

/*code somewhere*/ {
    Test t1 = new Test();
    t1.content = "Hello world!";
    Test t2 = (Test)t1.copy();
    System.out.println(t2.content);
}

这有一个问题,Copyable不是界面。但是,如示例所示,可以毫不费力地使用它,但语言级别不支持使用的类检查。换句话说,createCopy抽象方法不限于它复制的类,所有这些都取决于扩展Copyable类的程序员或扩展它的类。

积极的一面是,如果你在对象上调用.copy(),它必须返回与自身相同的对象。如果您愿意,可以返回null而不是例外。然后你好或没什么

但是,说实话,我真的不明白,为什么你的createCopy本地方法有参数。 它可能是一个静态的方法...虽然我甚至无法想象会进入该代码块的内容:

static <X extends Thing> X copy(X object) { ... }

愿你可以将实践与静态通用方法结合起来,结果会变得更加友好:

public interface Thing extends Cloneable {
    public static <X extends Thing> X copy(X thing) {
        Object clone = thing.clone();
        if (clone.getClass() != getClass())
            throw new RuntimeException("Copy has wrong type!");
        return (X)clone;
    }
}

public class ThingA implements Thing {
    public Object clone() { ... }
}

/*code somewhere*/ {
    ThingA a1 = new ThingA();
    ThingA a2 = Thing.copy(a1);
}

尽管如此,克隆方法受到异常而非语言限制的约束,但我认为这是最好的解决方案。