IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Surcharger une méthode clone()


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 187
    Par défaut Surcharger une méthode clone()
    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

  2. #2
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    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

  3. #3
    Membre averti
    Inscrit en
    Novembre 2007
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 45
    Par défaut
    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);
    	}

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par marcel_kobain Voir le message
    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);
    	}
    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 :
    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;
    	}
    Maintenant on peut encore améliorer cela de trois manière :
    1. 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);
      		}
      	}
    2. 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).
    3. 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 :
    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);
    		}
    	}
    a++

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 187
    Par défaut
    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.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    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.

  7. #7
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 187
    Par défaut
    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?

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    333
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 333
    Par défaut
    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 :

    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);
    		}
    	}
    Bon je m'incruste 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

Discussions similaires

  1. Surcharger une méthode dans une dll.
    Par Slashyguigui dans le forum C#
    Réponses: 5
    Dernier message: 22/09/2011, 09h15
  2. [Doctrine] Surcharger une méthode gérée par __call()
    Par Chekov dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 12/09/2009, 23h12
  3. Surcharger une méthode
    Par daddycorp dans le forum Langage
    Réponses: 6
    Dernier message: 16/12/2008, 10h55
  4. "Dé-surcharger" une méthode native javascript
    Par Takezo1584 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/08/2007, 12h37
  5. [Custom Tags] Problème avec une surcharge de méthode
    Par Strab dans le forum Taglibs
    Réponses: 19
    Dernier message: 26/08/2005, 16h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo