Прежде всего, обратите внимание, что интерфейс clone () не работает , поэтому его не следует использовать в новом коде. Лучше реализовать конструктор (ы) копирования вместо .
Однако, если вам действительно нужно сделать это, правильный способ для TopMost
- реализовать Cloneable
. Зачем? Говорит Эффективное Java, 2-е издание, пункт 11:
Так что же делает Cloneable
, учитывая, что он не содержит методов? Это определяет
поведение защищенной Object
реализации *1017*: если класс реализует
Cloneable
, метод клонирования Object
возвращает полевую копию объекта;
в противном случае он выбрасывает CloneNotSupportedException
. Это очень нетипичное использование
интерфейсов, а не один для эмуляции. Обычно реализация интерфейса
говорит что-то о том, что класс может сделать для своих клиентов. В случае Cloneable
,
он изменяет поведение защищенного метода в суперклассе.
Более того, Asub.clone
должно быть объявлено public
, а не protected
- иначе вы не сможете вызвать его из внешнего мира. Кроме того, если вы используете Java5 или выше, это законно и желательно, чтобы Asub.clone
возвращал Asub
, а не Object
(и аналогично для его суперклассов).
Вы не показываете членов в классах - реализации clone
в различных классах могут сильно отличаться в зависимости от типов членов в этом классе. А именно, если в классе есть непостоянные члены, вам необходимо тщательно их глубоко скопировать, в противном случае вы получите отдельные объекты, разделяющие их внутреннее состояние.
Однако, если у ваших классов есть только примитивные или неизменные поля, клонирование работает, как и ожидалось, хотя в ваших абстрактных классах есть много ненужных clone
методов, каждый из которых просто вызывает super.clone()
- вы можете быть лучше только с Asub.clone()
.
В качестве примечания: если Top a = (Top) super.clone()
не является опечаткой, вы вводите зависимость от базового класса в производный класс, что не очень хорошая идея.