| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Как правильно реализовать clone() |
| Автор: Dims 3.12.2007, 20:02 | ||
| Правильно ли я понимаю, что в общем случае mutable класс желательно должен иметь реализованный метод clone(), чтобы его объекты можно было копировать? Я хочу сделать несколько классов, каждый из который представлял бы собой составной индекс, то есть, был бы массивом целых чисел. Этот индекс должен будет иметь метод inc, который "увеличивал бы индекс на единицу", то есть, переходил бы к следующему индексу по определённым правилам. Для каждого наследника эти правила были бы свои, а вот основа -- массив целых чисел -- были бы общими. Я определил такой абстрактный класс
Как мне теперь реализовать метод clone()? Можно ли ограничиться реализацией в этом классе так, чтобы в наследниках работало правильно? Должен ли я использовать super.clone() при реализации? |
| Автор: Dims 3.12.2007, 20:32 | ||
Вот так правильно?
|
| Автор: Platon 3.12.2007, 21:55 |
| На самом деле интересный вопрос... IDEA подсвечивает с замечанием, что не вызван клон Object'а... Я эе на этом не заморачиваюсь, просто копирую все поля объекта. |
| Автор: sith 3.12.2007, 22:04 |
| ... ты же можешь сам и проверить... написав простой JUnit тест... ты ведь знаешь что должно получиться в результате твоего клонирования... сразу же и увидешь что имешь после выполнения этого кода |
| Автор: LSD 3.12.2007, 23:47 |
Да. При желании можно еще поставить try/catch и убрать CloneNotSupportedException. А каким макаром ты создаешь экземпляр объекта? Конструктором, что-ли? |
| Автор: Platon 4.12.2007, 10:39 |
| LSD, *CONFUSED* Нууууу, да. *SHOOT_HIMSELF* Ок, обращусь-ка я к докам за этим вопросом... |
| Автор: LSD 4.12.2007, 11:37 |
А теперь представь, что кто-то унаследуется от твоего класса. |
| Автор: Dims 4.12.2007, 11:43 |
| А в моём случае в наследниках переопределять clone() уже не будет нужно, как я понимаю. Правильный тип будет обеспечиваться сделанным вызовом super. Ясно. А если перехватывать исключение, то что делать в обработчике? В каких случаях может возникнуть исключение? Казалось бы, во всех наследниках метод должен работать правильно и исключение не может возникнуть никогда? А мне надо наследникам явно указывать implements Cloneable или они уже все по умолчанию унаследуют это свойство? |
| Автор: sith 4.12.2007, 11:46 | ||
... должны унаследовать... |
| Автор: Platon 4.12.2007, 16:14 |
| LSD, слава Богу, я клонированием направо и налево не занимаюсь (более того, в России на него мораторий), но в те скудных случаях когда делал его, проблем не возникало. |
| Автор: ressac 22.3.2008, 22:25 | ||||
Я не понимаю почему мы должны ставить возвращаемый тип класса "Object"? А не "CompoundIndex"? Ведь мы приводим super.clone(); к CompoundIndex ? и если честно не вижу разницу между КЛОНИРОВАНИЕ через метод clone() или просто копировать поля через конструктор? |
| Автор: w1nd 23.3.2008, 17:59 | ||
Разница в том, что Object.clone() клонирует любого наследника вашего класса полностью. Будет такая же дрянь, как если бы этот кто-то унаследовался бы от класса, в котором переопределён equals() и hashCode(). Штатная дрянь, так сказать. Я всегда реализую clone() без использования Object.clone(), а тот, кто делает наследников, должен соображать чуть-чуть. |
| Автор: ressac 23.3.2008, 18:36 |
| w1nd, не много понял из выше сказаного :( я яву только неделю учу, можно более доступным языком? |
| Автор: w1nd 23.3.2008, 23:13 | ||||
Вызов B.clone() скопирует и поля, объявленные в классе B. |
| Автор: ressac 23.3.2008, 23:21 |
| w1nd, млин всё вышел из ступора спасибо большое, спать могу теперь идти спокойно |
| Автор: LSD 24.3.2008, 13:05 | ||
А вот с этого момента поподробней, как надо реализовывать в наследниках clone() если в суперклассе он реализован без использования Object.clone()? |
| Автор: w1nd 24.3.2008, 22:18 | ||
Своим конструктором. |
| Автор: LSD 24.3.2008, 23:18 |
Это понятно. Как быть уверенным, что приватные поля суперклассов инициализированны корректно? |
| Автор: w1nd 24.3.2008, 23:41 | ||||||
Уверенным быть можно, если известна реализация (или имеются соглашения на этот счёт). В таком случае я не вижу способа так реализовать clone() в наследнике, чтобы унаследованный конструктор суперкласса не работал. Разве что самому что-то напортачить:
В принципе, наличие конструктора копирования уже даёт основания полагать, что копирование посредством этого конструктора будет корректным. Так же нельзя быть полностью уверенным в корректной инициализации класса при использовании Object.clone(). Например, такой класс может создать проблемы наследникам:
Речь не о том, что такая реализация не совсем верна, а о том, что таких реализаций - море. Поэтому предпочитаю насаждать более простую/понятную/надёжную схему. К тому же, она значительно быстрее работает Вообще, состояние класса должно быть воспроизводимо, иначе в клонировании вообще не видно смысла. |