2008-10-27 9 views
4

Java에서 약간의 문제가 있습니다. Modifiable이라는 인터페이스가 있습니다. 이 인터페이스를 구현하는 객체는 수정 가능합니다.Java의 필수 복제 가능 인터페이스

두 개의 수정 가능한 객체를받는 ModifyCommand 클래스 (명령 패턴 포함)도 있습니다.이 객체는 목록에서 더 바꿔 넣을 수 있습니다 - 내 질문이 아니기 때문에 이미 그 솔루션을 설계했습니다.)

ModifyCommand 클래스는 Modifiable 객체의 복제본을 만들어 시작합니다. 논리적으로, 나는 Modifiable 인터페이스가 Cloneable을 확장하도록 만들었다. 그런 다음 인터페이스는 구현 클래스가 다시 정의해야하는 clone() 메서드를 정의합니다.

그런 다음 ModifyCommand에서 firstModifiableObject.clone()을 수행 할 수 있습니다. 내 논리는 Modifiable을 구현하는 클래스는 Cloneable이 될 것이므로 Object에서 복제 메서드를 다시 정의해야한다는 것입니다.

클래스가 Modifiable을 정의한다고 정의하고 clone()을 재정의하려면 Object 클래스의 clone() 메서드가 Modifiable의 메서드를 숨 깁니다.

어떻게해야합니까? 나는 ...

감사합니다,

기욤를 "내가 잘못하고 있어요"라는 인상입니다.

편집 : 내가 clone() 일을 잊어 버리 리라 생각합니다. 나는 a) Modifiable 객체 (인터페이스 구현)에 전달 된 객체가 이미 복제되었거나 b) copy()와 같은 다른 메소드를 작성한다고 가정합니다.이 메소드는 기본적으로 Modifiable 객체의 deep 복사를 수행합니다. 또는 일반 솔루션이 작동 할 수도 있습니다 ...).

답변

9

, 당신은 당신이 원하는 동작을 얻을이 방법을 주조 제거 할 수 있습니다

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 
    } 
} 

를 푸는 객체를 확장하기 때문에, 이것은 여전히 ​​Object 클래스의 원래의 계약을 만족시킨다.수정 가능한 인터페이스에 의해 부과 된 추가 제약 때문에 clone() 메서드를 올바르게 수정하지 않는 코드는 컴파일되지 않습니다. 보너스로 호출 코드는 복제 메서드의 결과를 캐스팅 할 필요가 없습니다.

0

서명을 정확하게 개체에 정의 했습니까?

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

본문에 맞춤 코드를 추가해야합니다. Wikipedia이 놀랍도록 도움이되었습니다.

0

복제 방법에 대한 메소드 서명은 어떻게 생깁니 까? Clonable 인터페이스와 일치 시키려면 Object를 반환해야합니다. 수정 가능을 반환하는 것으로 선언하는 경우 문제가 될 수 있습니다.

1

수정할 수있는 인터페이스에서 복제 방법을 다시 정의 할 필요가 없습니다.

확인 문서 : http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

난 당신이 복제() 메소드를 오버라이드 (override) 모두를 강제하려고하는 것을 이해하지만, 당신이 그것을 할 수 없습니다. 또 다른 방법으로

, 당신은 인터페이스 클래스를 재정의 할 수 없습니다 :

클론() 메소드는 항상 Object.class를하지 Cloneable 인터페이스 오순절을 연결되어 있습니다. 인터페이스가 아닌 다른 객체에서 오버라이드 할 수 있습니다. 당신은 자바 1.5 이상을 사용하는 경우

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(); 
    } 
} 

내가 자바 5를 테스트 할 수 있습니다,하지만 난 그게 잘 작동 것 같아요.

+0

당신 말이 맞아요을 구현합니다. 좋은 작은 트릭! 그리고 의심 스럽지만 Java 5에서는 정상적으로 작동합니다. –

0

공용 클래스 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(); 

} 

}