如果您可以自由使用擴展,而不是執行,那麼你可以做的是這樣的:
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