Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно реализовать clone() 
:(
    Опции темы
Dims
Дата 3.12.2007, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Правильно ли я понимаю, что в общем случае mutable класс желательно должен иметь реализованный метод clone(), чтобы его объекты можно было копировать?

Я хочу сделать несколько классов, каждый из который представлял бы собой составной индекс, то есть, был бы массивом целых чисел. Этот индекс должен будет иметь метод inc, который "увеличивал бы индекс на единицу", то есть, переходил бы к следующему индексу по определённым правилам. 

Для каждого наследника эти правила были бы свои, а вот основа -- массив целых чисел -- были бы общими.

Я определил такой абстрактный класс

Код

public abstract class CompoundIndex implements Cloneable {
    
    protected int[] index;
    
    public CompoundIndex(int length) {
        index = new int[ length ];
    }
    
    public int length() {
        return index.length;
    }
}


Как мне теперь реализовать метод clone()? Можно ли ограничиться реализацией в этом классе так, чтобы в наследниках работало правильно? Должен ли я использовать super.clone() при реализации?
PM MAIL   Вверх
Dims
Дата 3.12.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



Вот так правильно?

Код

    public Object clone() throws CloneNotSupportedException {
        CompoundIndex ans = (CompoundIndex) super.clone();
        ans.index = index.clone();
        return ans;
    }

PM MAIL   Вверх
Platon
Дата 3.12.2007, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



На самом деле интересный вопрос...
IDEA подсвечивает с замечанием, что не вызван клон Object'а...
Я эе на этом не заморачиваюсь, просто копирую все поля объекта.
PM MAIL ICQ   Вверх
sith
Дата 3.12.2007, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 11.2.2007

Репутация: нет
Всего: 1



... ты же можешь сам и проверить... написав простой JUnit  тест... ты ведь знаешь что должно получиться в результате твоего клонирования... сразу же и увидешь что имешь после выполнения этого кода


--------------------
Там где ты ставишь глупые смайлики, я вбиваю восклицания знаки!!!
PM MAIL   Вверх
LSD
Дата 3.12.2007, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Dims @  3.12.2007,  20:32 Найти цитируемый пост)
Вот так правильно?

Да. При желании можно еще поставить try/catch и убрать CloneNotSupportedException.


Цитата(Platon @  3.12.2007,  21:55 Найти цитируемый пост)
Я эе на этом не заморачиваюсь, просто копирую все поля объекта.

А каким макаром ты создаешь экземпляр объекта? Конструктором, что-ли? smile 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Platon
Дата 4.12.2007, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



LSD, *CONFUSED*
Нууууу, да. *SHOOT_HIMSELF*
Ок, обращусь-ка я к докам за этим вопросом...
PM MAIL ICQ   Вверх
LSD
Дата 4.12.2007, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Platon @  4.12.2007,  10:39 Найти цитируемый пост)
Нууууу, да.

А теперь представь, что кто-то унаследуется от твоего класса.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Dims
Дата 4.12.2007, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 4
Всего: 11



А в моём случае в наследниках переопределять clone() уже не будет нужно, как я понимаю. Правильный тип будет обеспечиваться сделанным вызовом super.

Ясно. А если перехватывать исключение, то что делать в обработчике? В каких случаях может возникнуть исключение? Казалось бы, во всех наследниках метод должен работать правильно и исключение не может возникнуть никогда?

А мне надо наследникам явно указывать implements Cloneable или они уже все по умолчанию унаследуют это свойство?
PM MAIL   Вверх
sith
Дата 4.12.2007, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 11.2.2007

Репутация: нет
Всего: 1





Цитата(Dims @  4.12.2007,  11:43 Найти цитируемый пост)
А мне надо наследникам явно указывать implements Cloneable или они уже все по умолчанию унаследуют это свойство?


... должны унаследовать... 


--------------------
Там где ты ставишь глупые смайлики, я вбиваю восклицания знаки!!!
PM MAIL   Вверх
LSD
Дата 4.12.2007, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Dims @  4.12.2007,  11:43 Найти цитируемый пост)
А в моём случае в наследниках переопределять clone() уже не будет нужно, как я понимаю. Правильный тип будет обеспечиваться сделанным вызовом super.

Переопределять нужно будет если появятся новые поля и их тоже нужно будет клонировать (не все поля нужно клонировать, не изменяемые объекты клонировать не нужно).


Цитата(Dims @  4.12.2007,  11:43 Найти цитируемый пост)
Ясно. А если перехватывать исключение, то что делать в обработчике? В каких случаях может возникнуть исключение? Казалось бы, во всех наследниках метод должен работать правильно и исключение не может возникнуть никогда?

Оно может возникнуть, если класс не реализует интерфейс Cloneable, т.е. в твоем случае возникнуть не должно.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Platon
Дата 4.12.2007, 16:14 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



LSD, слава Богу, я клонированием направо и налево не занимаюсь (более того, в России на него мораторий), но в те скудных случаях когда делал его, проблем не возникало.
PM MAIL ICQ   Вверх
ressac
Дата 22.3.2008, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



Цитата(Dims @ 3.12.2007,  18:32)
Вот так правильно?

Код

    public Object clone() throws CloneNotSupportedException {
        CompoundIndex ans = (CompoundIndex) super.clone();
        ans.index = index.clone();
        return ans;
    }

Я не понимаю почему мы должны ставить возвращаемый тип класса "Object"?  
А не "CompoundIndex"? 
Ведь мы приводим super.clone(); к CompoundIndex ?

и если честно не вижу разницу между КЛОНИРОВАНИЕ через метод clone() или просто копировать поля через конструктор?


PM MAIL   Вверх
w1nd
Дата 23.3.2008, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(ressac @  22.3.2008,  22:25 Найти цитируемый пост)
и если честно не вижу разницу между КЛОНИРОВАНИЕ через метод clone() или просто копировать поля через конструктор?

Разница в том, что Object.clone() клонирует любого наследника вашего класса полностью.

Цитата(LSD @  4.12.2007,  11:37 Найти цитируемый пост)
А теперь представь, что кто-то унаследуется от твоего класса.

Будет такая же дрянь, как если бы этот кто-то унаследовался бы от класса, в котором переопределён equals() и hashCode(). Штатная дрянь, так сказать. 

Я всегда реализую clone() без использования Object.clone(), а тот, кто делает наследников, должен соображать чуть-чуть.



Это сообщение отредактировал(а) w1nd - 23.3.2008, 18:00


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
ressac
Дата 23.3.2008, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 345
Регистрация: 25.11.2006

Репутация: нет
Всего: 1



w1nd, не много понял из выше сказаного :( 

я яву только неделю учу, можно более доступным языком?
PM MAIL   Вверх
w1nd
Дата 23.3.2008, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(ressac @  23.3.2008,  18:36 Найти цитируемый пост)
w1nd, не много понял из выше сказаного :( я яву только неделю учу, можно более доступным языком?

Код
public static class A implements Cloneable {
        
    int i;
        
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException thrown) {
            throw new RuntimeException(thrown.getMessage(), thrown);
        }
    }
        
}
    
public static class B extends A {
        
    int j;
        
}

Вызов B.clone() скопирует и поля, объявленные в классе B.


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1123 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.