4

私はJavaで小さな問題を抱えています。Modifiable というインターフェイスがあります。このインターフェースを実装するオブジェクトは変更可能です。

また、2 つの Modifiable オブジェクトを受け取る ModifyCommand クラス (Command パターンを使用) もあります (リスト内でそれらをさらに交換する - それは私の質問ではありません。私はすでにそのソリューションを設計しています)。

ModifyCommand クラスは、Modifiable オブジェクトのクローンを作成することから始めます。論理的には、Modifiable インターフェイスが Cloneable を拡張するようにしました。次に、インターフェースは、その実装クラスが再定義する必要がある clone() メソッドを定義します。

次に、ModifyCommand で、firstModifiableObject.clone() を実行できます。私の論理では、Modifiable を実装するクラスは、Cloneable になるため、Object から clone メソッドを再定義する必要があります (それが私がやりたいことです)。

問題は、Modifiable を実装するクラスを定義し、clone() をオーバーライドしたい場合、Object クラスの clone() メソッドが Modifiable のメソッドを非表示にしていると言って、それができないということです。

私は何をすべきか?「やり方が間違っている」と思い込んでいる…

ありがとう、

ギヨーム。

編集: clone() のことを忘れると思います。a) Modifiable オブジェクト (インターフェースを実装する) に渡されたオブジェクトが既に複製されていると仮定するか、b) 基本的に Modifiable オブジェクトのディープコピーを行う copy() などと呼ばれる別のメソッドを作成します (または、一般的なソリューションが機能する可能性があります...)。

4

6 に答える 6

10

Java 1.5 以降を使用している場合は、次の方法で必要な動作を取得し、キャストを削除できます。

public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
    T clone();
}

public class Foo implements Modifiable<Foo> {
    public Foo clone() { //this is required
        return null; //todo: real work
    }
}

Foo は Object を拡張するため、これは依然として Object クラスの元の契約を満たしています。clone() メソッドを正しく改良しないコードは、 Modifiable インターフェースによって追加の制約が課せられるため、コンパイルされません。おまけに、呼び出しコードは clone メソッドの結果をキャストする必要はありません。

于 2008-10-27T18:08:58.300 に答える
1

インターフェイスModizableでcloneメソッドを再定義する必要はありません。

ドキュメントを確認してください:http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

全員にclonemethod()をオーバーライドさせようとしているとのことですが、それはできません。

別の方法では、インターフェイス上のクラスをオーバーライドすることはできません。

clone()メソッドは、クローン可能なインターフェイスではなく、常にObject.classに関連付けられます。インターフェイスではなく、別のオブジェクトでオーバーライドできます。

于 2008-10-27T17:51:21.223 に答える
1

Sean Reillyの答えに加えて、これはあなたの問題を解決するはずであり、よりタイプセーフです。それはコンパイルされ、JDK6で私と一緒にうまく動作します:

public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
    T clone();
}
public class Test implements Modifiable<Test> {
    @Override
    public Test clone() {
        System.out.println("clone");
        return null;
    }
    public static void main(String[] args) {
        Test t = new Test().clone();
    }
}

Java 5をインストールしていないため、テストできませんでしたが、問題なく動作すると思います。

于 2008-12-23T06:44:37.147 に答える
0

オブジェクト内の署名とまったく同じように署名を定義しましたか?

public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

これはコンパイルする必要があります-本文にカスタムコードを追加します。 ウィキペディアはこれに関して驚くほど役に立ちました。

于 2008-10-27T17:47:37.737 に答える
0

クローンメソッドのメソッドシグネチャはどのようになっていますか?Clonableインターフェースと一致させるには、オブジェクトを返す必要があります。変更可能を返すものとして宣言している場合は、それが問題になる可能性があります。

于 2008-10-27T17:48:37.407 に答える
0

public class CloningExample は Cloneable を実装します {

private LinkedList names = new LinkedList();


public CloningExample() {
    names.add("Alex");
    names.add("Melody");
    names.add("Jeff");
}


public String toString() {
    StringBuffer sb = new StringBuffer();
    Iterator i = names.iterator();
    while (i.hasNext()) {
        sb.append("\n\t" + i.next());
    }
    return sb.toString();
}


public Object clone() {
    try {
        return super.clone();
    } catch (CloneNotSupportedException e) {
        throw new Error("This should not occur since we implement Cloneable");
    }
}


public Object deepClone() {
    try {
        CloningExample copy = (CloningExample)super.clone();
        copy.names = (LinkedList)names.clone();
        return copy;
    } catch (CloneNotSupportedException e) {
        throw new Error("This should not occur since we implement Cloneable");
    }
}

public boolean equals(Object obj) {

    /* is obj reference this object being compared */
    if (obj == this) {
        return true;
    }

    /* is obj reference null */
    if (obj == null) {
        return false;
    }

    /* Make sure references are of same type */
    if (!(this.getClass() == obj.getClass())) {
        return false;
    } else {
        CloningExample tmp = (CloningExample)obj;
        if (this.names == tmp.names) {
            return true;
        } else {
            return false;
        }
    }

}


public static void main(String[] args) {

    CloningExample ce1 = new CloningExample();
    System.out.println("\nCloningExample[1]\n" + 
                       "-----------------" + ce1);

    CloningExample ce2 = (CloningExample)ce1.clone();
    System.out.println("\nCloningExample[2]\n" +
                       "-----------------" + ce2);

    System.out.println("\nCompare Shallow Copy\n" +
                       "--------------------\n" +
                       "    ce1 == ce2      : " + (ce1 == ce2) + "\n" +
                       "    ce1.equals(ce2) : " + ce1.equals(ce2));

    CloningExample ce3 = (CloningExample)ce1.deepClone();
    System.out.println("\nCompare Deep Copy\n" +
                       "--------------------\n" +
                       "    ce1 == ce3      : " + (ce1 == ce3) + "\n" +
                       "    ce1.equals(ce3) : " + ce1.equals(ce3));

    System.out.println();

}

}

于 2009-05-14T03:11:52.777 に答える