2016-06-21 3 views
0

У меня есть три класса:Java - Как реализовать метод клон для базовых и производных классов

Base extends Object 

Derived1 extends Base 

Derived2 extends Derived1 

Каждый из классов имеет свои собственные поля, которые должны быть клонированы. И у меня есть проблемы с пониманием лучшего способа реализовать clone и избежать дублирования кода. У меня есть следующая архитектура, но для меня это выглядит как худшее.

Derived2.clone(): он вызывает super.clone() и получает объект Derived1. Затем он вызывает новый Derived2(objOfDerived1), который вызывает super(objOfDerived1), который копирует все его поля, а затем в Derived2.clone() копируются все поля Derived2.

Как вы это скажете? Может быть, есть статьи, описывающие эту проблему?

UPD: идея может быть показано здесь

class Base implements Cloneable { 
    private String dataOfBase; 

    public Base() { 

    } 

    public Base(Base base) { 
     this.dataOfBase = base.dataOfBase; 
    } 

    @Override 
    public Object clone() { 
     Base base = new Base(); 
     base.dataOfBase = dataOfBase; 
     return base; 
    } 
} 

class Derived extends Base { 
    private String dataOfDerived; 

    public Derived(Base base) { 
     super(base); 
    } 

    @Override 
    public Object clone() { 
     Base base = super.clone(); 
     Derived derived = new Derived(base); 
     derived.dataOfDerived = dataOfDerived; 
     return derived; 
    } 
} 
+0

Если вы клонировать 'Derived2', ваш' super.clone() 'возвращает экземпляр 'Derived2', а не' Derived1' или 'Object'. – tkausl

+1

Почему вы сначала вызываете '' 'super.clone()' '' и вызываете '' 'новый Derived2''' после? Я бы просто назвал '' 'новый Derived2 (this);' '' и выполнил копирование в конструкторе копирования. Если вы не собираетесь использовать '' 'Object.clone()' '' любые способы. –

+0

@JornVernee, да, возможно, было бы более полезно – Ivan

ответ

3

Вы могли бы реализовать clone с точки зрения конструктора копирования:

class Base { 
    private String dataOfBase; 
    ... 
    public Base(Base other) { 
     this.dataOfBase = other.dataOfBase; 
    } 

    @Override 
    public Base clone() { // Covariant return type 
     return new Base(this); // calling copy constructor 
    } 
} 
class Derived extends Base { 
    private String dataOfDerived; 
    ... 
    public Derived(Derived other) { 
     super(other); 
     this.dataOfDerived = other.dataOfDerived; 
    } 

    @Override 
    public Derived clone() { 
     return new Derived(this); 
    } 
} 
0

А что-то вроде этого. Это позволит вам клонировать любой класс в иерархии напрямую и включать данные из всех классов выше в иерархии.

public class Derived1 extends Base { 

    public Derived1 clone(Derived1 foo) { 
     super.clone(foo); 
     // copy fields from Derived1 
     return foo; 
    } 

    public Derived1 clone() { 
     Derived1 foo = new Derived1(); 
     return this.clone(foo); 
    } 

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