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 :

héritage et type dans une fonction


Sujet :

Langage Java

Vue hybride

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 133
    Par défaut héritage et type dans une fonction
    Bonjour j'ai le code suivant :

    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 static void putfile() throws IOException
    	{
    		Enregistrement en = new Enregistrement();
    		Enumeration<Enregistrement>e ;
     
    		Enregistrement.setFw(new FileWriter(en.getNomfic(), false));
     
    		for (e=(Enumeration<Enregistrement>) v.elements(); e.hasMoreElements() ;)
    		{
    			en = e.nextElement() ;
    			en.write() ;
    		}		
    		getFw().close();		
    	}
    Je voudrai dériver cette classe Enregistrement, en Client, Mouvement, etc... et réutiliser cette fonction en remplaçant les occurrences Enregistrement par les classes héritées

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	public static void putfile() throws IOException
    	{
    		Client en = new Client();
    		Enumeration<Client>e ;
     
    		Client.setFw(new FileWriter(en.getNomfic(), false));
    ...
    v est un Vector du type Enregistrement ou Client suivant la version...

    Je voudrai savoir si cela est possible sans réécrire à chaque fois le code et si oui comment ?

    Merci d'avance.

  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,

    oui, si tu utilises les interfaces, cependant l'instanciation (Enregistrement, client, ...) doit ce faire a l'exterieur de putfile
    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 éprouvé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 133
    Par défaut
    Quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	public static void putfile() throws IOException
    	{
                              init_fic() ;
                              write_loop();
                              close_fic() ;
                  }
    Où init_fic, write_loop et close_fic sont des fonctions d'interface ? Je ne vois pas l'avantage à faire ça si je dois réécrire le code pour chaque classe héritée quand même.

    J'ai cherché avec la syntaxe du type <? extends Enregistrement> mais je ne suis arrivé nulle part...

  4. #4
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Salut,
    Oui, c'est parfaitement faisable : ça s'appèle le polymorhisme : le comportement d'une méthode est déterminé par le type instantié.

    Il suffit que les types héritant de Enregistrement redéfinissent la méthode write.

  5. #5
    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
    Si effectivement la classe client hérite de Enregistrement alors :

    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 static void putfile(Enregistrement en) throws IOException
    	{
    		//Enregistrement en = new Enregistrement(); doit être instancié a l'exterieur de la methode
    		Enumeration<Enregistrement>e ;
     
    		Enregistrement.setFw(new FileWriter(en.getNomfic(), false));
     
    		for (e=(Enumeration<Enregistrement>) v.elements(); e.hasMoreElements() ;)
    		{
    			en = e.nextElement() ;
    			en.write() ;
    		}		
    		getFw().close();		
    	}
    ca marche pour tous les types Enregistrement en redéfinissant les méthodes qui vont bien
    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

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

    Informations forums :
    Inscription : Octobre 2005
    Messages : 956
    Par défaut
    Bonjour,

    ce n'est pas tout à fait ce que vous avez demandé, mais pour ce qui est d'enregistrer des suites d'objets dans un fichier, la sérialisation est très efficace. Pourquoi se fatiguer à refaire ce qui existe déjà?

    Sinon, la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Enregistrement en = new Enregistrement();
    est la seule qui doit être réécrite en fonction du type.
    En utilisant le polymorphisme, c'est la méthode write du type réel de l'enregistrement qui est appelé. Cependant, c'est justement à l'instanciation que le type réel est déterminé. D'où la recommandation de sortir l'instanciation de la boucle.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 133
    Par défaut
    Merci pour les réponses, je suis débutant en java, c'est un exercice sur le séquentiel indexé donc pas de sérialisation possible.

    J'ai du mal à saisir la création d'un Enregistrement au tout début de ta méthode, simplement pour appeler getNomfic() !?
    J'avais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public final static String ficClient = "C:\\CLIENT.SEQ" ;
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public final static String ficMouvement = "C:\\MOUVCLIS.SEQ" ;
    Mais pour récupérer le nom du fichier de façon généraliste je n'ai pas trouvé d'autre moyen que d'instancier la classe.

    J'aurai voulu faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public abstract static String nomfic;
    ce qui est impossible. Passer le nom du fichier en paramètre est un bon compromis auquel je n'avais pas pensé.

    Le Writer est une excellente idée, je vais creuser la question merci encore.

    la seule qui doit être réécrite en fonction du type.
    donc je ferai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    	public static void putfile() throws IOException
    	{
     
    		Enregistrement en = new Enregistrement();
                              generic_putfile(en) ;
                 }
    avec dans generic_putfile le code réutilisable?

  8. #8
    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,


    J'aurais déjà plusieurs remarques sur ton code :
    • Apparemment setFw() et getFw() sont des méthodes static
      Je suppose que la méthode write() doit utiliser le FileWriter passée à ces méthodes
      C'est pas très propre ni réutilisable tout cela...
    • Comme la méthode putFile() est static, je suppose que le Vector v l'est aussi
      Ce n'est pas une très bonne idée à mon avis. Non seulement ce n'est pas très pratique mais c'est également source d'utilisation mémoire abusive et de problème d'accès concurrentiel en multi-thread.
      Tout ces objets static ont-ils une utilité pendant toute la durée de ton application ? Je ne pense pas...
      Une conception un peu plus orienté objet serait préférable !
    • J'ai du mal à saisir la création d'un Enregistrement au tout début de ta méthode, simplement pour appeler getNomfic() !?
    • Vector/Enumération... Cela fait partie de la vielle API de Collections et il serait préférable d'utiliser List/Iterator...
    • La fermeture du flux doit se faire dans un try/finally (personne ne le fait )




    Donc déjà j'essayerais de me débarrasser de tous ces static encombrant. La plupart du temps cela se résout par l'utilisation d'un paramètres (la variable n'est valable que pendant la durée de la méthode, contre toute l'application avec un static), et la classe Enregistrement ressemblerait à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Enregistrement {
     
    	public void writeTo(Writer w) {
    		// Ton code qui écrit dans le Writer
    	}
     
    }
    Et ma méthode de sauvegarde serait comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	public static void putfile(String fileName, List<Enregistrement> enregistements) throws IOException {
    		// On créee le fichier :
    		Writer writer = new FileWriter(fileName, false);
    		try {
    			// Pour tous les éléments :
    			for (Enregistrement e : enregistements) {
    				// On écrit dans le fichier :
    				e.writeTo(writer);
    			}
    		} finally {
    			// Et on ferme notre flux :
    			writer.close();
    		}
    	}
    Il n'y a plus aucune variable static !


    Il reste le problème des classes filles qui ne peuvent pas être utilisé avec cette méthode. En fait il suffit de changer le type du paramétrage Generics pour qu'il accepte les types fils, en transformant List<Enregistrement> en List<? extends Enregistrement>.

    Dans le même temps j'ajouterais deux autres modifs :
    • En remplaçant List par Iterable on se permet d'utiliser bien plus de source de donnée sans changer le code.
    • En découpant la méthode en deux on utilise réellement la puissance des flux et on se permet d'éventuelle évolution de manière simple.


    Ce qui donnerait :
    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
    	/** Sauvegarde dans un fichier. */
    	public static void putfile(String fileName, Iterable<Enregistrement> enregistements) throws IOException {
    		// On créee le fichier :
    		Writer writer = new FileWriter(fileName, false);
    		try {
    			putfile(writer, enregistements);
    		} finally {
    			// Et on ferme notre flux :
    			writer.close();
    		}
    	}
     
    	/** Ecriture dans un flux */
    	public static void putfile(Writer writer, Iterable<Enregistrement> enregistements) throws IOException {
    		// Pour tous les éléments :
    		for (Enregistrement e : enregistements) {
    			// On écrit dans le flux :
    			e.writeTo(writer);
    		}
    	}
    La première méthode se contente d'écrire dans un fichier, tandis que la seconde permet d'écrire dans n'importe quel flux.
    Si demain je dois écrire dans un autre type de flux (une socket, une console, un pipe, un buffer en mémoire, ...), je n'aurais qu'à englober l'appel vers putfile(Writer...)


    a++

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

Discussions similaires

  1. [Débutant] Paramètre Type dans une fonction
    Par noftal dans le forum VB.NET
    Réponses: 1
    Dernier message: 07/12/2013, 13h54
  2. [C#] Recupérer et comparer un Type dans une fonction
    Par Rycku dans le forum Windows Forms
    Réponses: 2
    Dernier message: 17/02/2007, 19h30
  3. [.NET2.0][C#]Passage type de classe dans une fonction
    Par SLE dans le forum Windows Forms
    Réponses: 4
    Dernier message: 06/06/2006, 15h48
  4. créer un type dans une fonction javascript
    Par amelhog dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 11/07/2005, 13h54
  5. créer un type hidden dans une fonction javascript
    Par amelhog dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/05/2005, 12h17

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