Bonjour,
j'ai une classe représentant une Personne, les attributs sont:
nom, prénom et sexe.
Je dois surcharger la méthode clone() en faisant un deep copy..
Je ne vois vraiment pas comment écrire cette méthode.
Pouvez vous m'aider?
Merci![]()
Bonjour,
j'ai une classe représentant une Personne, les attributs sont:
nom, prénom et sexe.
Je dois surcharger la méthode clone() en faisant un deep copy..
Je ne vois vraiment pas comment écrire cette méthode.
Pouvez vous m'aider?
Merci![]()
bonjour,
La réponse est la : clonage
Il n'y a pas de problème, il n'y a que des solutions.
Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran
Mes Articles : Mon premier article est sur le language D
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Il te suffit simplement d'implémenter la méthode clone dans ta Classe Personnes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return new Person(this.name, this.lastName, this.sexe); }
Salut,
Sauf que ceci est incorrect puisque tu ne respectes pas les règles du cloneage !
Il ne faut pas utiliser un constructeur mais appeler la méthode clone() hérité de Object, en implémentant Cloneable.
Exemple "basique" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class Person implements Cloneable { private String nom; private String prenom; private Date birthDay; private char sexe; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Il est inutile de dupliquer la valeur pour le "sexe", puisqu'il s'agit d'un type primitif et que le clone copiera alors sa valeur.
Pour les références c'est un peu plus compliqué car c'est la copie de la référence qui est effectué. Donc les deux références pointent vers le même objet en mémoire et il faut donc protéger cela par une copie explicite... sauf pour les types immuables (comme String) où cela est inutile et même contre-productif !
Donc cela devrait plutôt ressembler à ceci :
Maintenant on peut encore améliorer cela de trois manière :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 @Override protected Object clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); // On duplique l'attribut birthDay, car il n'est pas immuable : cloned.birthDay = (Date) cloned.birthDay.clone(); return cloned; }
- En supprimant l'exception de la déclaration de méthode. En effet cette dernière ne remontera que dans le cas où l'on implémente plus Cloneable. Inutile de se trainer une tel exception. Il est préférable de la cacher :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 @Override public Object clone() { try { Person cloned = (Person) super.clone(); cloned.birthDay = (Date) cloned.birthDay.clone(); return cloned; } catch (CloneNotSupportedException e) { // On remonte l'exception englobé dans une RuntimeException, // afin d'être quand même averti d'un éventuel problème : throw new RuntimeException(e); } }- Selon les besoins, en déclarant le classe public afin de faciliter son utilisation depuis l'extérieur (ce qui est autorisé par le langage).
- Enfin, depuis Java 5.0 il est possible de changer le type de retour, afin d'éviter un nouveau cast en sortie...
Ce qui donnerait au final :
a++
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 @Override public Person clone() { try { Person cloned = (Person) super.clone(); cloned.birthDay = (Date) cloned.birthDay.clone(); return cloned; } catch (CloneNotSupportedException e) { // On remonte l'exception englobé dans une RuntimeException, // afin d'être quand même averti d'un éventuel problème : throw new RuntimeException(e); } }
Merci pour votre aide, donc si ma classe contient des attributs qui sont uniquement des String, des int, des char et des double, je peux me contenter de:
?????????
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
Autre question: en quoi cette méthode utilise le DEEP COPY?
Merci d'avance.
comme tu n'as que des types primitif, elle n'utilise pas le deep copy. Comme la javadoc le dit, l'implémentation dans Object utilise le "shallow copy". Pour chaque attribut mutable de ton objet, tu devra donc après faire, à la main, une nouvelle instance, comme adiguba te l'a montré avec un date.
Merci pour la réponse.
Mais si on me demande de faire une méthode clone() en utilisant une deep copy et que ma classe contient que des attributs de type double et string... Je fais quoi?![]()
Bon je m'incrusteEn supprimant l'exception de la déclaration de méthode. En effet cette dernière ne remontera que dans le cas où l'on implémente plus Cloneable. Inutile de se trainer une tel exception. Il est préférable de la cacher :
Code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 @Override public Object clone() { try { Person cloned = (Person) super.clone(); cloned.birthDay = (Date) cloned.birthDay.clone(); return cloned; } catch (CloneNotSupportedException e) { // On remonte l'exception englobé dans une RuntimeException, // afin d'être quand même averti d'un éventuel problème : throw new RuntimeException(e); } }mais je comprends pas en quoi ce qu'il y a dessus est une bonne pratique ???
CloneNotSupportedException peut être remonté dans le cas où l'objet n'implémente pas l'interface clonable mais aussi dans le cas où la méthode a été overridé et que l'objet ne devrait pas être cloné.
Dans le deuxième cas ne vaudrait il mieux pas laisser le throws CloneNotSupportedException ??
Merci de m'éclairer![]()
Partager