Java: super.méthode clone() et à l'héritage
J'ai une petite question concernant la clone()
méthode en Java, utilisé comme super.clone()
en ce qui concerne l'héritage - où j'appelle la clone()
méthode dans la classe parent tout en haut de la touche.
La clone()
méthode est censé renvoyer une copie de cet objet, cependant, si j'ai trois classes dans un héritage heirachy et appel super.clone()
trois fois, pourquoi ne pas la classe la plus élevée dans l'héritage heirachy, un peu moins de la classe d'Objet, d'obtenir une copie de cette catégorie de retour?
Supposons que nous avons trois classes: A, B et C, où A -> B -> C ("inherit = ->)
Puis de l'appel super.clone()
dans la classe C, invoque clone()
dans B qui appelle super.clone()
, invoquer clone()
dans Un appel qui super.clone()
" cette fois de l'Objet.clone() est appelée". Pourquoi n'est-il pas une copie de la this
objet par rapport à la classe A qui revient de Object.clone()
? Qui semble logique pour moi.
Comment implémenter correctement
clone
stackoverflow.com/questions/1052340/...OriginalL'auteur Shuzheng | 2012-08-10
Vous devez vous connecter pour publier un commentaire.
Il semble que il ya au moins deux problèmes ici à l'œuvre:
On dirait que vous vous êtes confus sur la façon clone() est généralement mis en œuvre.
Il semble que vous êtes en train de penser que le clonage est une bonne idée (au lieu d'utiliser un constructeur de copie, d'usines ou de leur équivalent).
Ici est un exemple de mise en œuvre d'une méthode clone:
À noter que le résultat de
super.clone()
est immédiatement jeté à unFruit
. Qui permet à l'héritage de la méthode de modifier le Fruit-spécifiques des données sur les membres (fBestBeforeDate
dans ce cas).Ainsi, l'appel d'un enfant
clone()
méthode, alors qu'il va appeler les parents des clones, ajoute aussi ses propres modifications à la nouvelle copie. Ce qui vient de sortir, dans ce cas, sera unFruit
, pas unObject
.Maintenant, plus important encore, le clonage est une mauvaise idée. Copie des constructeurs et des usines de fournir beaucoup plus intuitive et facile d'entretien alternatives. Essayez de lire l'en-tête du Java Pratiques lien que j'ai attaché à l'exemple: qui résume certains de ces problèmes. Josh Bloch a également une discussion plus longue: le clonage devrait certainement être évitée. Voici un excellent résumé de paragraphe sur pourquoi il pense que le clonage est un problème:
Mon point est plus, depuis la classe d'Un appel super.clone() pour appeler l'Objet.clone(), pourquoi ne pas seulement la partie de cet objet qui appartiennent à la classe A d'avoir copié, tels que j'ai une infirmité objet uniquement avec des propriétés de la classe A. Quand je l'appelle super.clone() de la classe C, un pointeur this obtenir transféré à tout le chemin jusqu'à l'hiérarchique jusqu'à ce que super.clone @ catégorie A, tel que de l'Objet.clone sait "ce" objet je dois clone ??
-1 pour le "clonage" est une mauvaise idée." Il ya des moments où
clone
est justifiée et constructeur de copie ne fonctionnera pas. Envisager le clonage d'un objet et de ne pas connaître le type exact au moment de l'exécution. Dans ce cas, la classe du constructeur de copie utilisez-vous? clone est un peu difficile à obtenir le droit, mais quand c'est fait correctement, il fonctionne très bien. Voir ma réponse à un autre clone de question sur la façon de mettre en œuvre clone correctement stackoverflow.com/questions/1052340/...vous avez manqué le reste de la phrase où j'ai suggéré "copier les constructeurs et les usines." C'est assez facile à faire polymorphes usines. L'une de mes principales craintes quand il s'agit de clonage, c'est que je suis en espérant que tous les autres de la classe dans la hiérarchie mise en œuvre clone correctement (par exemple, absence de court-coupe peu profonde exemplaires).
vérifiez l'exemple de nouveau: d'abord il y a l'appel à super.clone() qui est jeté d'un enfant de la classe. Puis vous ajoutez des données à l'enfant en classe. Vous retournez alors à l'enfant.
OriginalL'auteur Bob Cross
Bien que la réponse est acceptée, je ne pense pas que cela répond pleinement à la première partie de la question (pourquoi passer dans les sous-classes qui fonctionne toujours).
Bien que je ne peux pas vraiment l'expliquer, je pense que je peux dissiper une partie de l'affiche de la confusion qui a été la même que la mienne.
Nous avons les classes suivantes
Le résultat de ceci est que
Class A: C
Class B: C
Class C: C
est imprimé sur la ligne de commande.
Donc, comme une question de fait, la
clone()
méthode deObject
en quelque sorte peut regarder bas la pile d'appel et de voir quel type d'objet au début de la chaîne invoquéeclone()
, puis, à condition que les appels de la bulle de sorte queObject#clone()
est en fait, un objet de ce type est créé. Si cela se produit déjà dans la classeC
, ce qui est étrange, mais il explique pourquoi le downcasts n'aboutissent pas à uneClassCastException
. J'ai vérifié avec l'OpenJDK, et il semble que cela vient par certaines Java magie noire mises en œuvre dans le code natif.OriginalL'auteur oarfish
C'est une spéciale méthode native. Cela a été fait pour rendre le clonage plus facile. Sinon, vous devrez copier tout le code de votre ancêtre des classes.
OriginalL'auteur evg
Si clone() dans B renvoie ce que clone() renvoie et clone() en C renvoie ce que le clone() dans B retourne ensuite clone() en C sera de retour quel que soit le clone() dans Un renvoie.
OriginalL'auteur Bhesh Gurung