Исключение ClassCast во время выполнения, когда я хочу преобразовать тип в его Sub для клонирования - PullRequest
0 голосов
/ 01 февраля 2012

IHello!

Я хочу клонировать объект "B", имеющий супертип "A".В методе clone () «B» я вызываю super.clone () (метод «A»).Этот метод возвращает тип «A» с полями, клонированными и установленными.

В методе clone () «B» я получаю возвращенный объект «pre-construct» из super.clone (), и яхочу продолжать клонировать его.Поэтому я должен привести его к объекту типа "B".

Нет проблем во время компиляции, но он вызывает сбой ClassCastException во время выполнения.

Можно ли превратить объект в его подтип?Или я должен клонировать все поля (даже поля класса "A") в методе "B" clone ()?

Спасибо.

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Правильное клонирование требует использования виртуального метода, который реализован на самом низком уровне, который поддерживает клонирование, и - в зависимости от того, как клонирование реализовано - либо переопределяется каждым уровнем, чем тот, который добавляет новые поля, которые требуютглубокое клонирование или переопределяется каждым производным классом, точка.

Если все реализации clone работали, вызывая super.clone до точки, где класс самого низкого уровня вызывает object.clone, затем вызываяclone для производного типа, который был приведен к базовому типу, даст объект этого производного типа.К сожалению, вера в то, что super.clone не работает, привела к тому, что многие люди используют конструкторы копирования вместо вызова super.clone, создавая, таким образом, неудачное самоисполняющееся пророчество.

Учитывая эту неудачную ситуацию, лучшее, что можно сделатьвероятно, что каждый класс, чей родительский объект предоставляет метод clone, который может не связываться с object.clone, предоставляет конструктор копирования protected, который принимает экземпляр своего типа, цепочки к конструктору копирования родительского класса, копирует все добавленные поляэтим производным типом, который публично предоставляется (или отображается на свойства, которые являются) или ссылаются на неизменяемые объекты, и клонирует любые поля этого производного типа, которые не являются публично доступными, и ссылаются на изменяемые объекты.Этот подход будет работать, но для каждого класса, производного от клонируемого класса, будет необходимо реализовать свое собственное переопределение метода виртуального клона, даже если единственное, что делает этот метод, - это вызывает конструктор защищенной копии своего собственного класса.

Если ваш родительский класс имеет не виртуальный метод клонирования, который вызывает какой-либо конструктор без виртуальной диспетчеризации, то невозможно правильно реализовать какой-либо производный класс.

0 голосов
/ 02 февраля 2012

Спасибо за ваши ответы, но я нашел решение: Я не знал, что в моем методе clone () моего суперкласса я должен был получить свой объект, вызвав super.clone () (native clone () из Object Class?) И привести его в мой тип. (Я сделал явное создание экземпляра MySuperType t = new MySuperType ()).

Теперь я получил MySuperType, который я могу понижать в своем подклассе: (MySubClass) sc = (MySubClass) super.clone ();

Спасибо, поэтому я напишу пост в своем блоге www.patate-chaude.fr !

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...