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

Java Discussion :

Création deux objets de même type


Sujet :

Java

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut Création deux objets de même type
    Bonjour,

    Je souhaite créer deux objets de même type, initialisés tous les deux par un troisième objet de même type en paramètre. Voici le code de 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
    	private SupplyChain sc;
    	private SupplyChain sc2;
    	private int demand;
    	private int fluct_demand;	
     
    	public SimulatedScenario(SupplyChain sc)
    	{
    		this.sc = new SupplyChain();
    		this.sc2 = new SupplyChain();
    		this.sc = sc;
    		this.sc2 = sc;		
    		demand = (Integer) sc.getSegmentoMercato().getDomanda();
    	}
    Ensuite, je souhaite modifier un attribut par l'appel d'un "setter" sur l'un des deux objets.
    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
    public void computeVarOptimumMarket(int market_state, int[] coalition){
                    ...
                    //compute current optimum point
    		current_optimum = new OttimoCosti(sc, coalition);
    		current_optimum.calcolaOttimo();
    		current_optimum.calcolaOttimiTotali();
    		
    		//sc2 = sc with new demand
    		sc2 = sc;
    		sc2.getSegmentoMercato().setDomanda(fluct_demand);
    		//compute new_optimum point for new demand
    		new_optimum = new OttimoCosti(sc2, coalition);
    		new_optimum.calcolaOttimo();
    		new_optimum.calcolaOttimiTotali();
                    ...
    }
    Or, je me rends compte que la valeur en question est aussi modifiée sur l'autre objet de même type, chose que je ne veux pas.
    J'ai remarqué que les ID de mes deux objets changeaient lorsque que j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		this.sc = sc;
    		this.sc2 = sc;
    et prennent tous deux le même ID que l'objet en paramètre.

    Comment puis-je contourner ce problème ? L'objectif étant s'initialiser les deux objets sc et sc2 avec les mêmes valeurs que l'objet en paramètre pour ensuite changer certaines valeurs de l'objet sc2 sans modifier celles de sc.

    Cordialement,
    Tehko

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 084
    Points : 7 996
    Points
    7 996
    Par défaut
    Il est logique que cela se comporte ainsi puisque sc et sc2 sont tout les 2 le meme objet lorsque tu fais ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.sc = sc;
    this.sc2 = sc;
    Pourquoi fait tu cela en fait, c'est cela qui pose problème.

  3. #3
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    this.sc = new SupplyChain(); // création d'un objet SupplyChain et mise dans la variable sc
    this.sc2 = new SupplyChain(); // création d'un objet SupplyChain et mise dans la variable sc2
    this.sc = sc; // attribution de sc à sc ... inutile (et sans doute enlevé à la compilation). sc vaut sc, il est inutile de tenter de l'attribuer à lui-même
    this.sc2 = sc; // attribution de sc à sc2, donc sc et sc2 sont maintenant 2 variables pointant vers le même objet et l'objet anciennement référencé par sc2 n'existe plus

    Ce bout de code est équivalent à :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    sc = sc2 = new SupplyChain();

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 561
    Points : 21 624
    Points
    21 624
    Par défaut
    Tu as besoin de créer ton propre "constructeur de copie," cette notion du C++ qu'on peut imiter en Java ainsi :

    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
    public class SupplyChain {
     
      int champ1;
      int champ2;
      // ...
     
     
      /** Construit un SupplyChain initialisé au même contenu qu'un autre. */
      public SupplyChain(SupplyChain original) {
        champ1 = original.champ1;
        champ2 = original.champ2;
        // ...
      }
     
    }

  5. #5
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    Wax78, je pensais qu'en faisant cela je pourrais récupérer les valeurs de l'objet en paramètre dans les deux autres objets.

    Hizin, c'est bien ce que j'ai remarqué. Les deux objets pointent vers l'objet en paramètre alors que je veux qu'ils copient seulement les variables contenues dans l'objet en paramètre.

    Citation Envoyé par thelvin Voir le message
    Tu as besoin de créer ton propre "constructeur de copie," cette notion du C++ qu'on peut imiter en Java ainsi :

    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
    public class SupplyChain {
     
      int champ1;
      int champ2;
      // ...
     
     
      /** Construit un SupplyChain initialisé au même contenu qu'un autre. */
      public SupplyChain(SupplyChain original) {
        champ1 = original.champ1;
        champ2 = original.champ2;
        // ...
      }
     
    }
    Thelvin, j'ai donc suivi ton conseil et écris le constructeur de copie:
    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
    public class SupplyChain {
    	private SegmentoMercato segmentoMercatoSC;
    	private ArrayList<Vector> AND_OR = new ArrayList<Vector>();
     
    	/**
             * Constructor allowing copy of an original SupplyChain
             * @param original
             */
    	public SupplyChain(SupplyChain original){
    		this.AND_OR = original.AND_OR;
    		.  .  .
                    .  .  .
                    .  .  .
    		this.segmentoMercatoSC = original.segmentoMercatoSC;
    	}
    Les objets n'ont donc plus le même ID mais en ce qui concerne les variables (ex: segmentoMercatoSC), chaque variable de sc pointe vers les mêmes ID que celle de sc2.
    Y a-t-il quelque chose que j'ai mal fait ? Ou mal compris ?

    Voici l'implémentation au cas où...:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class SimulatedScenario {
    	private SupplyChain sc;
    	private SupplyChain sc2;
            public SimulatedScenario(SupplyChain sc)
    	{
    		this.sc = new SupplyChain(sc);
    		this.sc2 = new SupplyChain(sc);
                    ...
             }
    ...
    }

  6. #6
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 084
    Points : 7 996
    Points
    7 996
    Par défaut
    Utlise des clones a la place des = dans ton constructeur de copie en l'implementant convenable dans les classes necessaire.

    Pour l'arraylist aussi,il faut en recréer une et soit remettre les elements soit les cloner aussi dans la nouvelle arraylist.

  7. #7
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    J'ai tenté ce que tu m'as dit. Je connaissais pas la méthode clone() donc j'ai adapté un code trouvé ici

    J'ai commencé à implémenter clone() dans mes classes. Voici par exemple l'implémentation dans la classe SegmentoMercato.java:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    	public SegmentoMercato clone() throws CloneNotSupportedException{
    		return (SegmentoMercato)super.clone();
    	}
    Ensuite, j'ai fais les modifs nécessaires dans mon constructeur de copie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	public SupplyChain(SupplyChain original) throws CloneNotSupportedException{
                    .  .  . 
                    .  .  .
                    .  .  .
    		this.segmentoMercatoSC = original.segmentoMercatoSC.clone();
    	}
    Et au final, j'ai quasi rien touché dans mon constructeur de classe SimulatedScenario:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public SimulatedScenario(SupplyChain sc) throws CloneNotSupportedException
    	{
    		this.sc = new SupplyChain(sc);
    		this.sc2 = new SupplyChain(sc);	
    	}
    Quand je lance le tout, une exception apparait:
    java.lang.CloneNotSupportedException: catena.struttura.SegmentoMercato
    at java.lang.Object.clone(Native Method)
    at catena.struttura.SegmentoMercato.clone(SegmentoMercato.java:26) -> correspond à la ligne de code return (SegmentoMercato)super.clone();
    at catena.struttura.SupplyChain.<init>(SupplyChain.java:60)
    at posteriori.probability.SimulatedScenario.<init>(SimulatedScenario.java:21)
    C'est la première fois que j'utilise clone() et je n'ai pas encore tout bien compris. D'où viendrait le problème ?

  8. #8
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 084
    Points : 7 996
    Points
    7 996

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 561
    Points : 21 624
    Points
    21 624
    Par défaut
    À noter que clone() ou un constructeur de copie, sont finalement deux manières de faire la même chose.

    clone() fait, à mon goût et par nécessité, trop de choses dans notre dos et qui compliquent certains bricolages à base d'extension. C'est pourquoi je penche naturellement vers le constructeur par copie.
    Mais il vaut mieux se décider une fois pour toutes entre l'un et l'autre, et faire toutes les copies, soit d'une manière, soit de l'autre.

  10. #10
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 084
    Points : 7 996
    Points
    7 996
    Par défaut
    Thelvin, tu n'as pas tort.

  11. #11
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    En fait j'avais simplement omis d'implémenter Clonable dans ma classe SegmentoMercato.
    Comme çà, ça va mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class SegmentoMercato implements Cloneable {
    	@Override
    	public SegmentoMercato clone() throws CloneNotSupportedException{
    		return (SegmentoMercato)super.clone();
    	}
            ...
    }
    Au final, il y avait certaines variables que je n'avais pas besoin de modifier donc j'ai fais un mix des deux solutions. Ainsi, j'obtiens le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class SupplyChain implements Cloneable{
    	public SupplyChain(SupplyChain original) throws CloneNotSupportedException{
    		this.AND_OR = original.AND_OR;
    		.  .  .
    		.  .  .
    		.  .  .
    		this.segmentoMercatoSC = original.segmentoMercatoSC.clone();
    	}
    ...
    }
    On a peut être vu mieux en terme d'implémentation ou de performances mais ça fait ce que je veux donc c'est l'essentiel.

    Merci à vous pour l'aide apporter.

    Juste pour savoir, quel est l'avantage de clone() par rapport à un constructeur de copie si ce n'est que ça m'a l'air un peu plus rapide à implémenter quand on a plusieurs niveau à prendre en compte ?

  12. #12
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 561
    Points : 21 624
    Points
    21 624
    Par défaut
    Citation Envoyé par Tehko Voir le message
    Juste pour savoir, quel est l'avantage de clone() par rapport à un constructeur de copie si ce n'est que ça m'a l'air un peu plus rapide à implémenter quand on a plusieurs niveau à prendre en compte ?
    - On peut appeler super.clone() et cela transmettra tous les champs de l'un vers l'autre, sans avoir besoin de le coder soi-même. Il ne reste qu'à cloner les objets des champs qu'on veut cloner et pas juste transmettre.
    - Ça permet la programmation générique. Quand on sait qu'on manie des objets clonables, et qu'on veut en faire des copies, on n'a qu'à appeler clone() dessus, sans se soucier de ce que sont ces objets. Alors qu'avec un constructeur, on doit d'abord se demander quel est le constructeur à appeler.

  13. #13
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    Ok, merci pour tes précisions Thelvin.

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

Discussions similaires

  1. Affectation de deux objet de même type.
    Par masterboy01 dans le forum Flex
    Réponses: 3
    Dernier message: 25/11/2010, 16h44
  2. Réponses: 1
    Dernier message: 07/11/2008, 09h48
  3. Réponses: 2
    Dernier message: 05/08/2008, 16h27
  4. 2 objets de même type dans une classe
    Par _R3nO_ dans le forum Hibernate
    Réponses: 2
    Dernier message: 28/02/2007, 16h12

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