Java의 필수 복제 가능한 인터페이스
-
04-07-2019 - |
문제
자바에서는 작은 문제가 있습니다. 수정 가능라는 인터페이스가 있습니다. 이 인터페이스를 구현하는 객체는 수정 가능합니다.
또한 수정 가능한 두 개의 개체를 수신하는 ModifyCommand 클래스 (명령 패턴 포함)가 있습니다 (목록에 추가로 교체 할 수 있습니다. 내 질문이 아닙니다. 이미 그 솔루션을 설계했습니다).
ModifyCommand 클래스는 수정 가능한 객체의 클론을 만드는 것으로 시작합니다. 논리적으로, 수정 가능한 인터페이스를 복제 할 수있게 만들었습니다. 그런 다음 인터페이스는 구현 클래스가 재정의 해야하는 클론 () 메소드를 정의합니다.
그런 다음 ModifyCommand에서 다음을 수행 할 수 있습니다 : FirstModifiableObject.clone (). 내 논리는 수정 가능한 클래스를 구현할 수있는 클래스가 복제 방법을 복제 할 수 있으므로 복제 방법을 재정의해야한다는 것입니다 (이것이 내가하고 싶은 일입니다).
문제는 클래스를 정의 할 때 수정 가능한 클래스를 구현하고 clone ()을 무시하고 싶을 때 객체 클래스의 클론 () 메소드가 수정 가능에서 숨겨져 있음을 진술하지 못합니다.
어떻게해야합니까? 나는 "내가 잘못하고있다"는 인상을 받고있다 ...
감사,
기 illa.
편집 : 복제품을 잊을 것이라고 생각합니다. a) 수정 가능한 객체 (인터페이스 구현)에 전달 된 물체가 이미 복제되었거나 b) 기본적으로 수정 가능한 객체의 깊은 코피를 수행하는 다른 메소드를 작성합니다. 또는 일반 솔루션이 작동 할 수도 있습니다 ...).
해결책
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는 객체를 확장하기 때문에 여전히 객체 클래스의 원래 계약을 만족시킵니다. CLONE () 메소드를 올바르게 정제하지 않는 코드는 수정 가능한 인터페이스에 의해 부과 된 추가 제약으로 인해 컴파일되지 않습니다. 보너스로, 통화 코드는 클론 방법의 결과를 캐스팅 할 필요가 없습니다.
다른 팁
인터페이스 수정 가능에서 복제 메소드를 재정의 할 필요가 없습니다.
문서 확인 : http://java.sun.com/j2se/1.4.2/docs/api/java/lang/clonable.html
나는 당신이 모든 사람이 Clone Method ()를 무시하도록 강요하려고한다는 것을 이해하지만, 그렇게 할 수는 없습니다.
다른 방법으로는 인터페이스에서 클래스를 무시할 수 없습니다.
클론 () 메소드는 항상 복제 가능한 인터페이스가 아닌 Object.class와 관련되어 있습니다. 인터페이스가 아닌 다른 객체에서 그것을 무시할 수 있습니다.
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로 테스트 할 수 없었지만 잘 작동 할 것 같습니다.
서명을 객체에있는 것처럼 정확하게 정의 했습니까?
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
이것은 컴파일해야합니다 - 신체에 사용자 정의 코드를 추가합니다. 위키 백과 놀랍게도 이것에 도움이되었습니다.
복제 방법의 메소드 서명은 어떻게 생겼습니까? 복제 가능한 인터페이스와 일치하려면 객체를 반환해야합니다. 수정 가능한 것으로 반환한다고 선언한다면 문제가 될 수 있습니다.
공개 클래스 클로닝 엑시 폴 (CloningExample) 클로닝 가능 {
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();
}
}