Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème pour sérialiser dans l exercice garage

Sujet résolu
    5 novembre 2014 à 14:44:33

    Bonjour j ai un problème de compréhension pour définir le type moteur par rapport à la classe moteur(abstraite) ainsi que pour la classe véhicule

    Voici pour la classe véhicule

    public class Vehicule implements Option,Serializable{
        private Moteur typeMoteur;
        private double prix;
        private String nom;
        private Marque nomMarque;
        private List<Option> options= new ArrayList<Option>();
       
        //constructeur
        public Vehicule(String nom){
            this.nom=nom;
       
        }
        public Vehicule(double prix, String nom, List<Option> options, Marque marque) {
            this.nom=nom;
            this.prix=prix;
            this.options=options;
            nomMarque=marque;
        }
        public Vehicule(Marque marque) {
            nomMarque=marque;
        }

    .......................................

    public void setMoteur(Moteur moteur) {
            typeMoteur=moteur;
        }

    Ma classe moteur

    public abstract class Moteur {
        public Moteur(String cylindre,Double prix){
            this.cylindre=cylindre;
            this.prix=prix;
        }
        private String cylindre;
        private Double prix;
       
        public Double getPrix(){
            return prix;
        }
        public String ToString(){
            return"";
        }
       
    }

    Et ma classe moteur essence

    public class MoteurEssence extends Moteur  {
        public MoteurEssence(String cyl, double prix){
            super(cyl,prix);
           
        }
        private TypeMoteur type;
        public void settype (TypeMoteur type){
            type=TypeMoteur.ESSENCE;
        }
       
    }

    Est ce que quelqu'un aurait une idée?

    Merci d avance

    • Partager sur Facebook
    • Partager sur Twitter
      5 novembre 2014 à 16:30:16

      Salut !

      Essayes de mettre ton code dans des balises "code", à gauche du boutons smileys.

      "J'ai un problème de compréhension" !? Donnes moi des détails ! Qu'est-ce que tu ne comprends pas exactement ? Ton titre indique que tu as un problème avec la sérialization ?

      A première vue, voici quelques problèmes :

      • Ton véhicule implémente la classe "Option", ce qui n'est pas logique : tu ne peux pas ajouter un véhicule dans un véhicule, au même titre qu'une climatisation !
      • Ton moteur à essence a un field de type "TypeMoteur". Cela signifie que tu as deux objets pour une même utilisation. En d'autres termes, ton "MoteurEssence" est de type "MoteurEssence" (Merci de l'info ! ^^ ). Comme tu peux le voir, c'est assez superflu.
      • Ensuite, ta méthode "setType()" définit le type de moteur. Dans la logique, cela signifie que je peux changer le type de moteur. Mais encore une fois, quel est l'intérêt ? Ça veut dire que je pourrai avoir un "MoteurEssence" de type "MoteurElectrique" ?
      • Enfin, cette méthode est inutile : le type de moteur passé en paramètre ne change rien, le "MoteurEssence" reste un MoteurEssence quoi qu'il arrive.

      Voilà, je t'ai indiqué quelques incohérences, maintenant il faut m'expliquer ton problème ;)

      -
      Edité par EclipseOnFire 5 novembre 2014 à 16:31:39

      • Partager sur Facebook
      • Partager sur Twitter
      Error 2006, MySQL server has gone away
        6 novembre 2014 à 13:11:26

        Merci pour ta réponse,

        Désolé pour les balises, je débute sur les forums ainsi qu en Java d ailleurs. Pour le problème de sérialisation cela vient des mes erreurs:

        Affichage des voitures :
        *************************
        
        java.io.InvalidClassException: com.sdz.moteur.MoteurEssence; no valid constructor
        	at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(Unknown Source)
        	at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
        	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
        	at java.io.ObjectInputStream.readObject0(Unknown Source)
        	at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
        	at java.io.ObjectInputStream.readSerialData(Unknown Source)
        	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
        	at java.io.ObjectInputStream.readObject0(Unknown Source)
        	at java.io.ObjectInputStream.readObject(Unknown Source)
        	at Garage.addVoiture(Garage.java:45)
        	at Main.main(Main.java:28)

        Je me doute bien que mon constructeur est mauvais mais je suis un peu perdu car  j essaie d utiliser une classe enum pour les types et je ne sais pas trop comment. D où le flou artistique pour le setType. Car dans mon code la classe TypeMoteur est la suivante:

        package com.sdz.moteur;
        
        public enum TypeMoteur {
        	DIESEL,
        	ESSENCE,
        	HYBRIDE,
        	ELECTRIQUE;
        }
        

        Donc j essaie juste de jouer avec l enum pour mettre ESSENCE dans MoteurEssence ce qui est assez space je le reconnais mais j ai du mal a voir comment faire.

        Si il y a moyen d'éclairer ma lanterne :)


        • Partager sur Facebook
        • Partager sur Twitter
          7 novembre 2014 à 21:05:41

          Bien sûr :)

          Commences par supprimer ton interface moteur ainsi que ses classes filles, si tu souhaites utiliser ton énumération. Ensuite, crées un constructeur privé dans ton Enum, en dessous des noms des types de moteur prenant en paramètre un nom et un prix. Ça devrait,  la fin, ressembler à ça :

          package com.sdz.moteur;
           
          public enum Moteur {
              DIESEL("Diesel", 2500.0D),
              ESSENCE("Essence", 2200.0D),
              HYBRIDE("Hybride", 7500.0D),
              ELECTRIQUE("Electrique", 4500.0D);
          
              private String nomType;
              private double prix;
          
              private Moteur(String type, double prix){
                  this.nomType = type;
                  this.prix = prix;
              }
          
              @Override
              public String toString(){
                  return this.nomType;
              }
          
              public String getNom(){
                  return this.nomType;
              }
          
              public double getPrix(){
                  return this.prix;
              }
          }

          Voilà ;)
          Du coup, ton moteur, ce sera un des éléments de ton Enum, et plus une instance de la classe Moteur ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Error 2006, MySQL server has gone away
            8 novembre 2014 à 20:50:46

            Effectivement vu comme ça l idée me semble sympa et pourtant il y a un ou deux trucs qui me pose problème.

            Lorsque dans le main (se trouvant dans l énoncé) de l exercice on donne:

            	   	 lag1.setMoteur(new MoteurEssence("150 Chevaux", 10256d));

            Je pensais que l on faisait appel à une classe fille de moteur sinon je ne voispas trop comment faire le new MoteurEssence via la classe enum Moteur et le fait que faire ceci dans la classe enum Moteur ne correspond plus au schéma UML donc ??????? suis un peu perdu.

            • Partager sur Facebook
            • Partager sur Twitter
              8 novembre 2014 à 22:14:37

              Ah je n'ai pas vu l'exercice en fait ^^. S'il fallait faire ça, alors c'est différent. Tu peux supprimer ton enum, elle devient inutile. A ce moment là, il te suffit simplement de créer des classes filles sans créer d'enum :

              public class MoteurEssence extends Moteur{
              //Et tout le barda
              }

              N'hésites pas si tu as un problème ;)

              • Partager sur Facebook
              • Partager sur Twitter
              Error 2006, MySQL server has gone away
                8 novembre 2014 à 23:58:50

                Merci pour ton aide, alors pour résumer car la je suis revenu au point de départ. Ce que j ai compris de l exercice est la suivante.

                Bon faire des classes filles de moteur (style MoteurElectrique,etc) faire une classe enum avec le type de moteur (moteurElec ......). J ai bien compris que cela faisait double emploi mais je pense que le but de l exer était d'utiliser ces différentes techniques. Et de là aller replacer le type de moteur de la classe enum plus le moteur venant de la classe MoteurElectrique via une méthode setMoteur que je pensais se trouver dans Véhicule.

                Alors si tu peux me donner ton avis sur la compréhension de cet énoncé car sans le comprendre ça va être dur de le résoudre

                • Partager sur Facebook
                • Partager sur Twitter
                  9 novembre 2014 à 13:16:58

                  Je n'arrive pas à trouver ton exercice x) Tu peux me donner l'URL s'il te plaît ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Error 2006, MySQL server has gone away
                    9 novembre 2014 à 21:40:09

                    Oui bien sur, voici l URL:

                    http://exercices.openclassrooms.com/assessment/63?login=363453&tk=9a723489b5061f0cc0228c9d51f37778&sbd=2014-10-29&sbdtk=63b1e9fcb8d475939489ea3edc1bfaa7

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 novembre 2014 à 2:13:30

                      Dans l'exercice, l'enum fait double emploi, mais permet en fait de connaître le type de ton moteur à partir de sa classe mère Moteur, sans avoir à utiliser de "instanceof" pour l'identifier.

                      Ta classe Moteur n'oblige pas aux classes filles d'avoir une méthode "setTypeMoteur", ce qui signifie que tes classes filles doivent déterminer leur TypeMoteur d'elles-mêmes, dans le constructeur. Tu peux donc enlever ta méthode "setTypeMoteur".

                      Un conseil : Lorsque tu es en face d'un diagramme UML et que tu as des classes, mets autant de setters et de getters que possible. Lorsque tu as devant toi une interface ou une classe abstraite, ne mets que ce dont tu as besoin d'implémenter. Ça permet d'éviter des erreurs ;)

                      Je sais pas si j'ai été assez clair, car ce sont des concepts assez difficiles à assimiler.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Error 2006, MySQL server has gone away
                        15 novembre 2014 à 22:06:07

                        ok alors voici ce que j ai cru comprendre dans ton message
                        public abstract class Moteur {
                        	public Moteur(String cylindre,Double prix, TypeMoteur typeMoteur){
                        		this.cylindre=cylindre;
                        		this.prix=prix;
                        		this.setTypeMoteur(typeMoteur);
                        		
                        	}
                        	private String cylindre;
                        	private Double prix;
                        	private String typeMoteur;
                        	
                        	public void setCylindre(String cylindre){
                        		this.cylindre=cylindre;
                        	}
                            public void setPrix(Double prix){
                        		this.prix=prix;
                        	}
                            public void setTypeMoteur(TypeMoteur typeMoteur){
                            	this.typeMoteur=typeMoteur.toString();
                        	
                            }	
                        	public Double getPrix(){
                        		return prix;
                        	}
                        	public String ToString(){
                        		return"";
                        	}
                        	
                        }
                        Je passe le type moteur a travers un constructeur de ma classe mère moteur ce qui donne dans une classe fille:
                        import java.io.Serializable;
                        
                        
                        public class MoteurEssence extends Moteur implements Serializable {
                        	 private String typeMoteur;
                        	 public MoteurEssence(String cyl, double prix){
                        	        super(cyl,prix,TypeMoteur.ESSENCE);        
                        	 }
                            
                        }
                        

                        là, je passe le type enum via le constructeur de ma classe mère. Mais tout ça me donne une erreure de type :

                        no valid constructor

                        Donc la je suis un peu largué


                        • Partager sur Facebook
                        • Partager sur Twitter
                          16 novembre 2014 à 0:41:58

                          Parfait ! :)

                          Juste un truc, j'avais spécifié que tu pouvais enlever le "setter" pour ton "TypeMoteur" dans la classe mère, pour éviter d'avoir des "MoteurEssence" de type "MoteurElectrique". Et pourquoi as-tu un field de type "String" nommé "typeMoteur" dans ta classe "MoteurEssence" ?

                          L'erreur vient du fait que les classes que tu essaies de sérialiser n'ont pas de constructeurs sans arguments. La "serialization" java a besoin d'un constructeur sans arguments pour charger les objets. Il te suffit juste de spécifier deux constructeurs dont un sans arguments. Une autre méthode consiste à créer une classe qui permettra d'enregistrer les données de ton objet, et on utilisera cet objet pour la "serialization". Mais cette seconde méthode est plus complexe, et je pense que ce n'est pas le but de l'exercice ;)

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Error 2006, MySQL server has gone away
                            20 novembre 2014 à 12:48:05

                            Un grand merci à toi,c est déjà plus clair mais maintenant et comme tu t en doute vu mon niveau j ai encore 2 problèmes:

                            J ai donc des classes filles (MoteurEssence) d une classe mère moteur. J ai défini String ToString dans moteur. J appelle donc après tout ça ma classe MoteurEssence pour l'afficher en pensant que si

                            public abstract class Moteur {
                            	public Moteur(){
                            	}
                            	public Moteur(String cylindre,Double prix, TypeMoteur typeMoteur){
                            		this.cylindre=cylindre;
                            		this.prix=prix;
                            		this.typeMoteur=typeMoteur.toString();
                            	}
                            	private String cylindre;
                            	private Double prix;
                            	private String typeMoteur;
                            	
                            	public void setCylindre(String cylindre){
                            		this.cylindre=cylindre;
                            	}
                                public void setPrix(Double prix){
                            		this.prix=prix;
                            	}	
                            	public Double getPrix(){
                            		return prix;
                            	}
                            	public String ToString(){
                            		return typeMoteur+" "+cylindre+" "+prix;
                            	}
                            	


                            je ne redefini pas la methode ds la classe fille, lorsque je fais un System.out.println(moteurEssence) je passe par la méthode ToString de la classe mère, mais ca ne marche pas donc ????????

                            public class MoteurEssence extends Moteur implements Serializable {
                            	   
                            	 public MoteurEssence(String cyl, double prix){
                            	        super(cyl,prix,TypeMoteur.ESSENCE);        
                            	 }
                            	 
                                
                            }

                            Et mon second problème est pour la creation du fichier txt pour la sauvegarde, je ne sais pas trop où le créer.Faut il le créer dans le constructeur et mettre une condition du style si il est deja la ne plus le creer?

                            Encore merci pour ton aide

                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 novembre 2014 à 18:55:18

                              Tu ne dois pas implémenter la méthode "ToString()" mais bien la méthode "toString()". Attention : la casse est très importante en Java. Un conseil : lorsque tu désires implémenter une méthode, ajoute l'annotation "@Override" devant, comme ça ton compilateur te signalera si jamais tu n'implémentes pas la bonne méthode ! ;)

                              public abstract class Moteur{
                              
                                  //...
                              
                                  @Override//Cette annotation indique au compilateur que tu implémentes une méthode.
                                  public String toString(){
                                      return typeMoteur + " " + cylindre + " " + prix;
                                  }
                              
                                  //...
                              
                              }

                              Non attention, il ne faut jamais sauvegarder tes classes dans un constructeur ! Il est impossible d'enregistrer une classe que tu n'a pas encore instanciée ! Le mieux est d'ajouter deux méthodes dans ta classe : "save()" et "load()" qui se chargeront de sauvegarder et d'enregistrer ton objet.

                              public class clazz implements Serializable{
                              
                                  public static final String PATH_TO_FILE = "test.txt";
                              
                                  public void save() throws IOException{
                                      //...
                                  }
                              
                                  public void load() throws ClassNotFoundException, IOException{
                                      //...
                                  }
                              }

                              De là, tu peux enregistrer tes objets. Le mieux est de placer le fichier dans le répertoire courant, comme l'indique ma constante "PATH_TO_FILE". Sinon, pour tes vérifications, tu le fais comme tu veux, du moment qu'elles sont dans ces deux méthodes. Tu pourras appeler ces méthodes dans ton "main" par exemple, lors du chargement de ton programme. En cas de besoin, tu peux les rendre statiques aussi.

                              -
                              Edité par EclipseOnFire 20 novembre 2014 à 18:56:24

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Error 2006, MySQL server has gone away
                                21 novembre 2014 à 7:38:38

                                Salut, je pense avoir trouvé mon problème. Lorsque je sauve, je sauve une liste qui a les valeurs de mon moteur. Lorsque je lis par après cette liste, il manque les valeurs du moteur == null.

                                save

                                List<Vehicule> voitures= new ArrayList<Vehicule>();
                                oos.writeObject(voitures);


                                load

                                List<Vehicule> readObject = (List<Vehicule>)ois.readObject();

                                Et la je ne comprends pas pourquoi?

                                Merci pour l aide



                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 novembre 2014 à 19:45:58

                                  En principe, tu ne sérialise pas une "List<Vehicule>" mais une "ArrayList<Vehicule>". Donc veilles à récupérer une "ArrayList<Vehicule>" et non une "List<Vehicule>".

                                  Pour ne pas avoir à te soucier de cette erreur, soit tu sérialize une "ArrayList" que tu cast en "ArrayList"  lors de la lecture, soit tu crée un petite classe comme celle-ci :

                                  public class Serializer implements Serializable{
                                      public Vehicule[] vehicules;
                                  }

                                  Tu pourras l'utiliser de cette manière :

                                  //Ecriture
                                  List<Vehicule> list //...
                                  Serializer serializer = new Serializer();
                                  serializer.vehicules = (Vehicule[])list.toArray();
                                  oos.writeObject(serializer);
                                  
                                  //Lecture
                                  Serializer serializer = (Serializer)ois.readObject();
                                  List<Vechicule> list = new ArrayList<Vehicule>();
                                  for(Vehicule i : serializer.vehicules){
                                      list.add(i);
                                  }

                                  C'est plus complexe, mais plus sûr ! De plus, tu peux ajouter d'autres valeurs dans ton Serializer.


                                  -
                                  Edité par EclipseOnFire 21 novembre 2014 à 19:46:34

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Error 2006, MySQL server has gone away
                                    25 novembre 2014 à 10:37:52

                                    Merci encore pour ton aide, j ai fini par trouver le problème.Ma classe abstract Moteur n était pas serializable donc impossible de sauvegarder les données de ces classes filles. Voilà pour finir deux petites questions; comment faire pour marquer le post comme résolu et faut il compresser tout le projet pour l envoyer pour correction?

                                    Super boulot en tout cas pour le support sans qui je ne serai plus là je pense ;-)

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      25 novembre 2014 à 18:57:21

                                      Pas de problème !

                                      N'oublies pas de mettre ton sujet en résolu !

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Error 2006, MySQL server has gone away

                                      problème pour sérialiser dans l exercice garage

                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                      • Editeur
                                      • Markdown