7

I would like to create a generic interface for those two classes but I'm not sure how to specify the generics the right way.

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

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

I tried it this.

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

}

But I'm still able to do things like this, which shouldn't be allowed.

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

4 回答 4

6

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

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

于 2013-08-26T11:59:16.917 回答
2

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

于 2013-08-27T06:42:21.350 回答
0

你在寻找

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

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

于 2013-08-26T11:58:30.377 回答
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如果需要,您可以 return 代替异常。然后你得到了好或没有

但是,老实说,我真的不明白,为什么你的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);
}

尽管如此,克隆方法仍受例外而不是语言限制的约束,但我认为这是最好的解决方案。

于 2017-05-10T14:49:58.880 回答