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

Langage Java Discussion :

Cloner un objet


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut Cloner un objet
    Bonjour à tous !

    J'ai un petit problème pour cloner un objet. J'ai lu le tuto de Yann D'Isanto dans les cours de Java , mais rien n'y fait.

    J'ai plusieurs questions :

    - Est-ce que l'on peut cloner un objet dans une méthode de la classe de cet objet ? (une méthode qui appartient à cet objet) ou il faut le faire dans une classe extérieure ? (ce qui m'arrangerait pas du tout)

    - Et ensuite, voici mon problème. J'ai l'impression que le clone de mon objet Echiquier ne marche pas, pourtant, aucune exception ne survient pendant l'opération. En fait, il attribue mon objet Echiquier à l'objet EchiquierCloné, c'est à dire qu'il modifie l'objet original.

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public boolean uneMethode() {
    ...
    // TODO: Le clone de l'échiquier marche pas ! Ca modifie le véritable échiquier ?!
    // On clone l'échiquier
    Echiquier echiquierClone = (Echiquier) this.clone();
    // On joue un coup virtuellement
    echiquierClone.joueCoup(position, autrePosition);
    ...
    }
    Cette méthode si situe dans ma classe Echiquier, et cette classe étend Cloneable.
    Voici les attributs principaux de ma classe Echiquier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // La taille du plateau est une constante
    public static final int TAILLE_PLATEAU = 8;
    // L'échiquier possède un tableau de cases
    private Case plateau[][] = new Case[TAILLE_PLATEAU][TAILLE_PLATEAU];
    Et ce tableau de Cases est initialisé comme ça dans mon constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    int camp;  // 0 => blanc ; 1 => noir
    for(camp = 0; camp < 2; camp++) {
        final int dernierNumero = TAILLE_PLATEAU - 1;
        final int ligneArriere = camp * dernierNumero; 
        final int ligneAvant = 1 + camp * (TAILLE_PLATEAU - 3); 
        final boolean couleurNoire = (camp == 1); 
     
        // Figures
        plateau[ligneArriere][0] = new Case(ligneArriere, 0, new Tour(couleurNoire, "T")); 
        plateau[ligneArriere][7] = new Case(ligneArriere, 7, new Tour(couleurNoire, "T"));
        plateau[ligneArriere][2] = new Case(ligneArriere, 2, new Fou(couleurNoire, "F"));
        plateau[ligneArriere][5] = new Case(ligneArriere, 5, new Fou(couleurNoire, "F"));
        plateau[ligneArriere][3] = new Case(ligneArriere, 3, new Dame(couleurNoire, "D"));
        plateau[ligneArriere][4] = new Case(ligneArriere, 4, new Roi(couleurNoire, "R"));
        plateau[ligneArriere][1] = new Case(ligneArriere, 1, new Cavalier(couleurNoire, "C"));
        plateau[ligneArriere][6] = new Case(ligneArriere, 6, new Cavalier(couleurNoire, "C"));
        // Pions
        plateau[ligneAvant][0] = new Case(ligneAvant, 0, new Pion(couleurNoire, ""));
        plateau[ligneAvant][1] = new Case(ligneAvant, 1, new Pion(couleurNoire, ""));
        plateau[ligneAvant][2] = new Case(ligneAvant, 2, new Pion(couleurNoire, ""));
        plateau[ligneAvant][3] = new Case(ligneAvant, 3, new Pion(couleurNoire, ""));
        plateau[ligneAvant][4] = new Case(ligneAvant, 4, new Pion(couleurNoire, ""));
        plateau[ligneAvant][5] = new Case(ligneAvant, 5, new Pion(couleurNoire, ""));
        plateau[ligneAvant][6] = new Case(ligneAvant, 6, new Pion(couleurNoire, ""));
        plateau[ligneAvant][7] = new Case(ligneAvant, 7, new Pion(couleurNoire, ""));
     
         // Aperçu du tableau de positions des pièces
         //  ...   ...   ...  ...
         // (2,0) (2,1) (2,2) ...
         // (1,0) (1,1) (1,2) ...
         // (0,0) (0,1) (0,2) ...
    }
    Et enfin, voici la méthode clone() dans toujours la même classe (Echiquier) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    // Clone l'objet echiquier
        // TODO: Marche pas !
        @Override
        public Object clone() {
            Echiquier echiquier = null;
            try {
                echiquier = (Echiquier) super.clone();
            } catch (CloneNotSupportedException exception) {
                System.err.println("" + exception.getMessage());
            }
            // On clone le plateau de jeu
            echiquier.plateau = (Case[][]) plateau.clone();
            // TODO: Il faut peut être ici cloné aussi les pièces du plateau
            // mais comment faire ?
     
            // On retourne l'échiquier cloné
            return echiquier;
        }
    -Est ce que les classes Case, Pion, Tour, Fou, Dame, Roi et Cavalier doivent aussi étendre Cloneable ? (Ce n'est pas le cas pour l'instant)

    Merci pour les personnes qui prendront le temps de regarder mon portable et me proposer une solution !

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    961
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 961
    Par défaut
    Je pense que vous devriez parcourir "plateau" pour cloner les "Case" une par une, car les celles-ci contiennent des données spécifiques à un échiquier. Pour Pion, Tour, Fou, Dame, Roi et Cavalier, celà dépend : si elles contiennent des données spécifiques à un échiquier, alors oui.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Voici de nouveau ma méthode clone() de la classe Echiquier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Clone l'objet echiquier
        // TODO: Marche pas !
        @Override
        public Object clone() {
            Echiquier echiquier = null;
            try {
                echiquier = (Echiquier) super.clone();
            } catch (CloneNotSupportedException exception) {
                System.err.println("" + exception.getMessage());
            }
            // On clone le plateau de jeu
            echiquier.plateau = (Case[][]) plateau.clone();
            // TODO: Il faut peut être ici cloné aussi les pièces du plateau
            for (int i = 0; i < TAILLE_PLATEAU; i++) {
                for (int j = 0; j < TAILLE_PLATEAU; j++) {
                    echiquier.plateau[i][j] = (Case) plateau[i][j].clone();
                }
            }
            // On retourne l'échiquier cloné
            return echiquier;
        }
    Mais si je fais ça, que la classe Case implémente l'interface Cloneable ou non, ça me fait une erreur pour la ligne en gras :
    "clone() has protected access in java.lang.Object"
    Pourquoi cette erreur ??

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    961
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 961
    Par défaut
    Est-ce que Case implémente l'interface Cloneable?

    Citation Envoyé par womannosky Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (Case) plateau[i][j].clone();
    Un peu ambigu comme écriture, mieux vaut ajouter les parenthèses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Case) plateau[i][j]).clone();
    Au fait, quel est le type de plateau?

    (Note : j'ai modifié mon message précédent au moment où vous postiez.)

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Citation Envoyé par BugFactory Voir le message
    Je pense que vous devriez parcourir "plateau" pour cloner les "Case" une par une, car les celles-ci contiennent des données spécifiques à un échiquier. Pour Pion, Tour, Fou, Dame, Roi et Cavalier, celà dépend : si elles contiennent des données spécifiques à un échiquier, alors oui.
    Ok, je veux bien mais comment faire ? Pouvez vous m'aider ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Ok pour votre dernier message.
    Case n'implémente pas l'interface Cloneable pour l'instant, il le faut ?

    Votre écriture comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ((Case) plateau[i][j]).clone();
    Ca ne fonctionne pas, j'ai le même message

    Et plateau est de type Case[][].

    Merci pour votre aide

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Par défaut
    Oui. Non seulement Case doit implémenter Cloneable, mais en plus tu dois redéfinir la méthode clone() héritée de Object pour cloner tous les attributs complexes s'il y en a et relever la visibilité à public.

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Ok, Verbose, merci !
    Je viens donc d'implémenter Cloneable dans ma classe Case, et d'y ajouter ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Clone la case
        @Override
        public Object clone() {
            Case caseClone = null;
            try {
                caseClone = (Case) super.clone();
            } catch (CloneNotSupportedException exception) {
                System.err.println("" + exception.getMessage());
            }
            // On retourne la case cloné
            return caseClone;
        }
    Grâce à cette méthode, je n'ai plus l'erreur de tout à l'heure.

    Et comme les cases contiennent des pièces, il faut que je fasse pareil pour la classe Piece ??
    Si oui, ça va être interminable...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment cloner un objet ?
    Par rei.uchiwa dans le forum Langage
    Réponses: 2
    Dernier message: 29/04/2010, 22h48
  2. Cloner un objet
    Par jeandadaf dans le forum VB.NET
    Réponses: 10
    Dernier message: 18/10/2009, 14h26
  3. [POO] cloner un objet (et tous ses sous objets ?)
    Par Merfolk dans le forum Langage
    Réponses: 11
    Dernier message: 05/05/2008, 16h23
  4. [WD9] Cloner un objet
    Par Romanops dans le forum WinDev
    Réponses: 12
    Dernier message: 06/02/2006, 15h52
  5. Cloner un objet : comment créer l'instance ?
    Par phplive dans le forum Langage
    Réponses: 8
    Dernier message: 29/05/2005, 18h27

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