あなたは、あなたがこのようことを行うことができ、実装の代わりに拡張子を自由に使用されている場合には:その後、
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
ローカルメソッドにパラメータがある理由を理解していません。 それは、静的メソッドである可能性が... altrough私もそのコードブロックに行くだろうか想像することはできません。
static <X extends Thing> X copy(X object) { ... }
あなたは、静的な汎用的な方法でpraticeを組み合わせることができ、その結果は、もう少しフレンドリーになっ可能性があり:
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);
}
それでも、クローニング法ではなく、言語制限の例外によって規制が、私は、これははるかに最善の解決策だと思います。
これで彼は、彼が望んでいないものを正確に行うことができます。ジェネリックスは、ジェネリックスの目的とは全く反対の1つのタイプのクラスのみを使用することを妨げるものではありません。 – giorashc