0

オブジェクトのディープ コピーをポリモーフィックに作成する方法の可能性をネットで検索しているときに、フィールドを複製できないなど、この方法に関する多くの問題を解決すると主張する解決策を見つけました。ソリューションは、実装内で保護されたコピー コンストラクターの使用を組み合わせ、基本的には次のようになります (参照ページからコピーされた例)。clone()finalclone()

public class Person implements Cloneable
{
    private final Brain brain; // brain is final since I do not want 
                               // any transplant on it once created!
    private int age;

    public Person(Brain aBrain, int theAge)
    {
        brain = aBrain; 
        age = theAge;
    }

    protected Person(Person another)
    {
        Brain refBrain = null;
        try
        {
            refBrain = (Brain) another.brain.clone();
            // You can set the brain in the constructor
        }
        catch(CloneNotSupportedException e) {}
        brain = refBrain;
        age = another.age;
    }

    public Object clone()
    {
        return new Person(this);
    }

    …
}

clone()方法はBrain、同様の方法で実施することができる。

メソッドのドキュメントにclone()基づくと、このメソッドのすべての「コントラクト」は「絶対的な要件ではなく」、「返されたオブジェクトは を呼び出すことによって取得する必要がある」というsuper.clone()のは単なる慣例のようです。

では、この実装は実際には正しくないのでしょうか? なんで?

もしそれが正しいなら、なぜデザインパターンにならなかったのですか?これの欠点は何ですか?

ありがとう、ペトル

4

3 に答える 3

1

クローン可能なインターフェイスを実装してクローンを作成しようとしていますが、推奨されるクローン作成の契約に従っていません。

あなたは基本的にコピーコンストラクターを使用して新しいオブジェクトを作成しています.私の質問は、なぜクローン可能を実装する必要があるのですか?

cloneable を実装している場合は、契約を尊重する必要があります。clone メソッド内でコピー コンストラクターを使用する場合、子クラスのクローンは子クラスのオブジェクトではなく、代わりに Person クラスのオブジェクトになるため、このアプローチはお勧めしません。

また、クローン可能なインターフェースの代わりにコピーコンストラクターを使用することは、よりオブジェクト指向のアプローチであることを指摘したいと思います。

于 2013-04-03T16:34:55.000 に答える
0

では、この実装は実際には正しくないのでしょうか? なんで?

CloneNotSupportedException がドロップされるため、安全ではありません。

Brain が複製可能でない場合、新しい Person には Brain がありません :) オブジェクト構造に、制御していない (ソースへのアクセスがない) オブジェクトがある場合はどうなりますか?

なぜデザインパターンにならなかったのか

類似したオブジェクトからすべてのオブジェクトを複製できるわけではないためです。通常、既存の隣接オブジェクトよりも、この特定の新しいオブジェクトがどのように見えるかをよく知っている環境オブジェクトがあります。

于 2013-04-03T15:47:56.823 に答える