2010-10-21 14 views

Répondre

1

Il est nécessaire de passer outre clone() si la classe B définit les champs non membres primitve mutables. Ceux-ci doivent être copiés en profondeur explicitement au sein de B.clone(). Si B contient uniquement des membres de données primitives et/ou immuables, A.clone() fera le travail.

Pour une explication plus détaillée, voir this earlier answer of mine à une question similaire.

+0

Si vous appelez _super.clone_ dans chaque implémentation _clone_, vous finirez par appeler _Object # clone_. Et cette méthode fera une copie superficielle de tous les champs de données. Je pense que OP a bien compris. –

+0

@Nikita, la première version de ma réponse était en effet incorrecte, mais je l'ai depuis mis à jour, maintenant je crois que c'est juste. –

+0

Si l'un des ancêtres de 'B' définit' clone' en termes de constructeur de copie plutôt qu'en termes de 'Object', alors' B' doit faire de même. Si 'B' utilise un constructeur de copie même si tous ses ancêtres sont chaînés à' base.clone', il oblige tous ses descendants à utiliser également un constructeur de copie. Personnellement, je trouve ennuyeuse la notion de méthodes de clonage qui font autre chose que de chaîner 'base.clone', mais de telles méthodes sont hélas très courantes. – supercat

0

Si la classe parente, et tous les ancêtres, met en œuvre sa méthode Clone en appelant sa méthode classe parente Clone, tout le chemin jusqu'à Object.clone, et si aucun des champs ajoutés par les références de maintien de la sous-classe des choses qui devraient être modifiable sur un objet sans affecter l'autre, alors on peut simplement hériter du clone sans le surcharger. Si la classe parente implémente la méthode clone comme décrit ci-dessus mais que la sous-classe ajoute des champs qui doivent eux-mêmes être clonés, le meilleur modèle est que la sous-classe appelle base.Clone puis clone les champs appropriés.

Si la classe mère ou tout ancêtre ne met pas sa méthode Clone comme décrit ci-dessus, mais utilise plutôt un constructeur de copie, puis la classe dérivée, et toutes les classes de base qui en découlent) doivent passer outre Clone à faire de même, que la classe de base ajoute de nouveaux champs.

Malheureusement, je ne connais pas de moyen agréable de déterminer à quelle catégorie appartient une classe parente. Si une classe parent prend en charge Clone en appelant base.Clone, il serait regrettable pour une classe dérivée de rompre inutilement la chaîne en implémentant un constructeur de copie. D'un autre côté, si la classe parent implémente Clone en tant que constructeur de copie, une classe de base qui ne le fait pas aura une sémantique rompue.