2008-10-27 3 views
4

У меня небольшая проблема в Java. У меня есть интерфейс под названием Modifiable. Объекты, реализующие этот интерфейс, являются Модифицируемыми.Обязательный клонный интерфейс в Java

У меня также есть класс ModifyCommand (с шаблоном Command), который получает два модифицируемых объекта (чтобы поменять их в списке дальше - это не мой вопрос, я уже разработал это решение).

Класс ModifyCommand начинается с создания клонов модифицируемых объектов. Логически, я сделал мой Модифицируемый интерфейс расширяет Cloneable. Затем интерфейс определяет метод clone(), который должны быть переопределены его классами реализации.

Затем, в ModifyCommand, я могу сделать: firstModifiableObject.clone(). Моя логика заключается в том, что классы, реализующие Modifiable, должны будут переопределить метод clone из Object, поскольку они будут Cloneable (это то, что я хочу сделать).

Дело в том, что когда я определяю классы реализует Модифицируемое, и я хочу переопределить clone(), он не позволит мне, заявив, что метод clone() из класса Object скрывает объект из Modifiable.

Что мне делать? Я нахожусь под впечатлением, что «я делаю это неправильно» ...

Спасибо,

Гийом.

Редактировать: он думает, что я забуду клон(). Я либо а) предполагаю, что объект, переданный объекту Modifiable (реализующий интерфейс), уже клонирован или b) создает другой метод, называемый, например, copy(), который будет в основном делать глубокую копию объекта Modifiable (или, может быть, общее решение будет работать ...).

ответ

9

Если вы используете 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.Код, который не уточняет метод clone(), не будет компилироваться из-за дополнительных ограничений, накладываемых интерфейсом Modifiable. В качестве бонуса код вызова не должен выдавать результат метода clone.

0

Вы определили подпись именно так, как она есть в объекте?

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

Это должно скомпилировать - добавить пользовательский код в тело. Wikipedia был неожиданно полезен на этом.

0

Как выглядит ваша подпись метода для вашего метода клонирования? Чтобы он соответствовал интерфейсу Clonable, ему пришлось бы возвращать объект. Если вы объявляете его возвратом Модифицируемого, это может быть проблемой.

1

Вам не нужно переопределять метод клонирования на интерфейсе Модифицируемый.

Проверьте документацию: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

Я понимаю, что вы пытаетесь заставить все переопределить метод Clone(), но вы не можете это сделать.

По-другому, вы не можете изменить класс на интерфейсе: метод

Клона() всегда ассоциируется ничуть Object.class и не клонируемый интерфейс. Вы просто можете переопределить его на другом объекте, а не в интерфейсе.

1

Добавляя к ответу Шона Рейли, это должно решить вашу проблему и более безопасно. Он собирает и работает нормально со мной на 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, потому что я не он установлен, но я предполагаю, что это будет работать нормально.

+0

Вы правы. Хороший маленький трюк! И, как вы подозревали, на Java 5 отлично работает. – 2008-12-30 15:53:24

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

} 

}

 Смежные вопросы

  • Нет связанных вопросов^_^