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
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:
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.
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 :
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.
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
}
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
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.
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
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?
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
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);
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
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 ;-)
× 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.
Je passe le type moteur a travers un constructeur de ma classe mère moteur ce qui donne dans une classe fille: