Ваш простой вопрос: почему super.clone()
приведен к MyClass
? Это связано с тем, что объявление HerClass.clone()
указывает возвращаемое значение HerClass
, поэтому вы должны привести его к нужному типу.
Теперь по более сложному вопросу: как super.clone()
может на самом деле вернуть экземпляр MyClass
? На самом деле мне было трудно найти ответ, но я нашел какой-то ответ в «Эффективной Java» Джошуа Блоха. На фоне Object.clone()
все еще есть какая-то "магия", которую я не совсем понимаю.
Пункт 11 из книги:
На практике программисты предполагают, что если они расширяют класс и вызывают
super.clone из подкласса, возвращаемый объект будет экземпляром
подкласса. Единственный способ, которым суперкласс может обеспечить это
функциональность заключается в возвращении объекта, полученного путем вызова super.clone.
Если метод clone возвращает объект, созданный конструктором, он будет
иметь неправильный класс. Следовательно, , если вы переопределите метод клонирования в
Нефинальный класс, вы должны вернуть объект, полученный с помощью вызова
super.clone . Если все суперклассы класса подчиняются этому правилу, то
вызов super.clone в конечном итоге вызовет метод Object clone,
создание экземпляра правильного класса.
Изначально я пытался ответить на ваш вопрос, написав программу, не зная, что вам всегда приходилось звонить super.clone()
. Мой самодельный метод клонирования для HerClass
возвращал новый экземпляр HerClass
, сгенерированный из конструктора (new HerClass()
). Код скомпилирован, но он не выполнен при выполнении, когда я пытался привести (MyClass) super.clone()
. Только методы, связанные с Object.clone()
, могут возвращать значение, которое является экземпляром одного из их подтипа .
Обратите внимание, что если HerClass.clone()
явно не реализовано, по умолчанию он просто возвращает Object.clone()
. Метод по умолчанию имеет доступ protected
, но поскольку вы вызываете его из подкласса, это не проблема.