如果您可以自由使用扩展,而不是执行,那么你可以做的是这样的:
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
抽象方法并不局限于它所复制的类,所有这一切都取决于扩展类的程序员或扩展它的类。
积极的一面是,如果您在对象上调用.copy()
,它必须返回一个与它自己相同的对象。如果您愿意,您可以返回null
而不是例外情况。然后你得到好或没有。
但是,老实说,我不是很懂,为什么你的createCopy
本地方法有一个参数。 这可能是再一个静态方法...... altrough我甚至无法想象会进入该代码块:
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);
}
尽管如此,克隆方法是一个例外,而不是语言的限制规定,但我认为这是目前最好的解决方案。
这仍然可以让他做到他不想做的事。泛型不会阻止您仅使用一种类型的类,因为这将与泛型相反。 – giorashc