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 :

Question classe abstraite


Sujet :

Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut Question classe abstraite
    Bonjour,

    en déclarant une classe abstraite Oeuvres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public abstract class Oeuvres {
            protected String titre;
            protected int année;
    	protected void lire(){
    		System.out.println("Je lis une oeuvre");
    	}
     
    	abstract void ranger();
    	abstract void vendre();
     
    }
    puis dans une autre classe en définissant la méthode void ranger() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Livres extends Oeuvres{
     
    	public Livres(String pTitre, int pAnnée){
    		this.titre=pTitre;
    		this.année=pAnnée;
    	}
     
    	void ranger(){
    		System.out.println("Je range un livre");
    	}
    }
    ensuite dans une autre classe en définissant la méthode void vendre() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Magazines extends Oeuvres{
     
    	void vendre() {
    		System.out.println("Je vend un magazine");
    	}
    }
    ma classe Livres a un problème, qui se corrige en définissant dans cette classe la méthode void vendre() (méthode que j'ai déclarée dans Magazines).

    Cela signifie-t-il que ma classe abstraite Livres doit obligatoirement définir toutes mes méthodes non définies de ma classe mère (à savoir ici Oeuvres) ?
    Car bien que je définisse ma méthode void vendre() dans la classe suivante (Magazines), la classe Livres semble ne pas prendre cela en compte.

    Merci d'avance, j'espère avoir été clair !
    (bien que la question soit simple, je l'ai peut être un peu compliqué )

  2. #2
    Membre expérimenté Avatar de Grom61736
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2013
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Février 2013
    Messages : 169
    Par défaut
    Cela signifie-t-il que ma classe abstraite Livres doit obligatoirement définir toutes mes méthodes non définies de ma classe mère (à savoir ici Oeuvres) ?
    Dans le bout de code donné, la class Livre n'est pas abstraite.

    1) Soit Livre est une classe "normale" et tu redéfinis les méthode de la classe abstraite
    2) Soit Livre est une classe abstraite et tu ne dois pas redéfinir toutes les méthodes.

    Car bien que je définisse ma méthode void vendre() dans la classe suivante (Magazines), la classe Livres semble ne pas prendre cela en compte.
    Quelque chose a dû m'échapper car je ne vois pas le lien entre le classe Livre et Magazine.

  3. #3
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Par défaut
    Bonjour,

    1-
    abstract void ranger();
    abstract void vendre();
    Les méthodes déclarées sans bloc dans une classe abstraite ou dans un interface sont implicitement abstrait, donc inutile de mettre "abstract".

    2- Les méthodes abstraits dans une classe abstraite ou dans un interface doivent être impérativement définit dans une classe concrète qui étend la classe ou implémente l'interface.

    Avec ce que tu veux, je pense que c'est mieux de faire:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface rangeable{
    	public void ranger();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface vendable{
    	public void vendre();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public abstract class Oeuvres {
            protected String titre;
            protected int année;
    	protected void lire(){
    		System.out.println("Je lis une oeuvre");
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Livres extends Oeuvres implements rangeable{
     
    	public Livres(String pTitre, int pAnnée){
    		this.titre=pTitre;
    		this.année=pAnnée;
    	}
     
    	public void ranger(){
    		System.out.println("Je range un livre");
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Magazines extends Oeuvres implements vendable{
     
    	public void vendre() {
    		System.out.println("Je vend un magazine");
    	}
    }
    Fait attentetion avec la visibilité protected.

    A+.

  4. #4
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Ah oui, j'avais oublié que les méthodes abstraites ne peuvent être définies que dans des classes abstraites (Livres ne l'est pas). Donc ça OK.

    En fait Grom61736, j'ai mal réfléchis car en parlant des deux classes Livres et Magazines, je me suis dit "la classe Magazine va "comprendre" que j'ai définis la méthode ranger() dans Livres" mais c'est complètement faux comme raisonnement, je viens de m'en rendre compte.

    Merci andry.aime pour ton détail de solution, bien que les interfaces soient dans le prochain chapitre

    Grâce à vos réponses et en voyant mon code comme ça, je crois avoir davantage compris cette partie.

    Question finale quand même : étant donnée qu'on peut déclarer plusieurs méthodes dans différentes classes abstraites, quand vient le moment de donner ces méthodes à un objet, on peut en oublier... Du coup, peut-on avoir une sorte de centralisation de toutes les méthodes abstraites déclarées ? Ou bien peut-on peut être déclarées toutes ces méthodes dans la classe abstraite mère puis les définir dans les filles ?

  5. #5
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par devdav Voir le message
    Question finale quand même : étant donnée qu'on peut déclarer plusieurs méthodes dans différentes classes abstraites, quand vient le moment de donner ces méthodes à un objet, on peut en oublier...
    N'importe quel IDE te sortira une erreur sur la classe non abstraite héritant de ta classe abstraite en te disant qu'elle ne définit pas toutes les fonctions abstraites. Ils te permettront meme de créer les prototypes tout seul

    Citation Envoyé par devdav Voir le message
    Ou bien peut-on peut être déclarées toutes ces méthodes dans la classe abstraite mère puis les définir dans les filles ?
    Je ne comprends pas la question. Mais il faut voir les classes abstraites ou les interfaces comme des contrats. Elles garantissent qu'une classe qui peut etre instanciée (donc non-abstraite) implémentera les fonctions abstraites de la classe mere. On est donc sur qu'on peut appeler ces fonctions quelle que soit la classe fille. J'insiste sur ces points parce que l'exemple que tu postes en #1 n'a aucun interet du point de vue objet/héritage donc je ne suis pas sur que ce concept est clair dans ta tete.

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    N'importe quel IDE te sortira une erreur sur la classe non abstraite héritant de ta classe abstraite en te disant qu'elle ne définit pas toutes les fonctions abstraites.
    ... parce que toutes les fonctions abstraites déclarées dans la classe abstraite principale doivent être déclarées (dans la mère ou les filles) avant de faire la classe non abstraite, c'est ça ?

    Voici un exemple pour ma dernière question :

    - Je crée ma classe main, ça OK;
    - Je crée ma classe abstraite Arbre dans laquelle je déclare :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public abstract class Arbre {
    	protected String couleur;
    	protected int nombre;
    	abstract void planter();
    	abstract void couper();
    }
    - Je crée une classe abstraite fille Sapin où je définit void planter() et void () couper mais en plus je crée la méthode void arroser() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public abstract class Sapin extends Arbre {
    	void planter(){
    		System.out.println("Plantation d'un sapin");
    	}
    	void couper(){
    		System.out.println("Il faut le couper");
    	}
    	void arroser(){
    		System.out.println("Il faut arroser");
    	}
    }
    - Puis je crée ma classe normale Pins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Pins extends Sapin{
    	public Pins(String pCouleur, int pNombre){
    		this.couleur=pCouleur;
    		this.nombre=pNombre;
    	}
    }
    - Enfin je reviens dans ma classe main pour y créer mon objet Sapin s :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Main {
    	public static void main(String[] args) {
     
    		Pins p = new Pins("bleu", 200);
    		p.couper();
    		p.planter();
    		p.arroser();
    	}
    }
    Et là, tout fonctionne. Du coup, j'aurai aimé savoir si il y avait une astuce pour connaitre, au final, quelles sont toutes les méthodes abstraites que l'on a déclarée ? Car en regardant la classe abstraite principale Arbre, on en voit que deux, puisque j'en ai déclarée une autre dans Sapin
    (genre un : System.out.print(lister_toutes_les_methodes_asbtraites_inclues_dans_mes_classes_abstraites_(donc_mère_et_filles));
    Je sais que cette fonction n'existe pas hein, c'est juste pour mieux comprendre.

    Je suis désolé d'embrouiller un peu la situation... En tout cas, c'est vachement sympa vos interventions, merci beaucoup !
    Après ça, je vous embête plus, promis.

    [Edit] Je viens de voir les interfaces. C'est pas mal du tout en fait. C'est comme une classe abstraite sans les implémentations (que l'on fait dans les classes normales). Je comprend maintenant ta réponse andry.aime

  7. #7
    Membre expérimenté Avatar de Grom61736
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2013
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Février 2013
    Messages : 169
    Par défaut
    Oulà ! :S

    Je n'ai aucune idée pour ta fonction "lister_toutes_les_methodes_asbtraites_inclues_dans_mes_classes_abstraites_(donc_mère_et_filles)".
    D'ailleurs, je ne sais pas s'il y a un cas où c'est "utile" vu que ton IDE te dit quoi réimplémenter.

    Cependant, si c'est la liste des méthodes possibles par ta class, tu peux utiliser la reflexivité Liste des méthodes publiques d'une classe.

  8. #8
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Par défaut
    Bonjour,

    Tu peux étendre une classe abstraite par une autre classe abstraite qui peut implémenter les méthodes déclarer par la classe mère et déclarer de nouvelles méthodes abstraites. Mais dans la classe concrète finale, toutes les méthodes abstraites depuis l'origine doivent tout être implémentés soit par elle même, soit par une classe ancêtre. J'espère que tu l'as déjà compris.

    Par contre ton soucis est la visibilité des méthodes, je ne sais pas si tu as lu le tutoriel du lien que j'ai donné ou non mais tu as tendance à n'utiliser que default et protected dans les classes abstraites.

    A+.

  9. #9
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par devdav Voir le message
    ... parce que toutes les fonctions abstraites déclarées dans la classe abstraite principale doivent être déclarées (dans la mère ou les filles) avant de faire la classe non abstraite, c'est ça ?
    Une classe instanciable (donc non abstraite) doit avoir toutes ses méthodes déclarées. Et que ce soit sur elles memes ou l'une de ses classes meres, peu importe. Mais du coup, une classe instanciable qui hérite d'une classe abstraite doit implémenter toutes les méthodes abstraites.

    Citation Envoyé par devdav Voir le message
    Et là, tout fonctionne. Du coup, j'aurai aimé savoir si il y avait une astuce pour connaitre, au final, quelles sont toutes les méthodes abstraites que l'on a déclarée ? Car en regardant la classe abstraite principale Arbre, on en voit que deux, puisque j'en ai déclarée une autre dans Sapin
    En général ton IDE t'indique si les méthodes de ta classe sont abstraites ou non. Ceci dit, au vu de tes questions (et des exemples), je suis curieux de savoir, d'apres toi, à quoi ca sert les méthodes abstraites ?

  10. #10
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Citation Envoyé par andry.aime Voir le message
    je ne sais pas si tu as lu le tutoriel du lien que j'ai donné ou non
    Non pas encore, j'essaie d'abord de comprendre cette partie et je me penche juste après sur la visibilité.

    Citation Envoyé par hwoarang Voir le message
    à quoi ca sert les méthodes abstraites ?
    Ce que j'ai compris, c'est que la force de Java c'est d'utiliser les objets (= des parties de programme que l'on réutilise). Si on crée des objets qui possèdent tous des attributs communs, on regroupe ces attributs dans une classe. Cette classe pourra être abstraite si on ne peut pas créer directement des objets avec elle.

    Une classe abstraite permet de définir des méthodes (abstraites ou non) qui seront utilisées par d'autres classes, méthodes qui seront communes et/ou spécifiques à ces sous classes. Si la méthode est commune, on la définit et l'implémente dans la classe abstraite; si elle est spécifique, on la définit dans la classe abstraite et on l'implémente dans la sous classe. C'est ça ?

    Du coup, une méthode abstraite est une méthode définit dans une classe abstraite qui sera utilisée par des objets créés par des sous classes à cette abstraite ?

    Merci pour votre aide.

  11. #11
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    En fait, l'intérêt d'une méthode abstraite, c'est justement qu'elle est utilisée par les classes qui ne se chargent pas de l'implémenter.

    Si c'était juste une méthode prévue pour les sous-classes, on aurait pas besoin de la déclarer abstraite. On la déclarerait dans les sous-classes et c'est marre. C'est une méthode à l'usage de la classe mère et des classes utilisatrices de la classe mère, mais ce sont les sous-classes qui se chargent de fournir cette classe abstraite.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par devdav Voir le message
    Une classe abstraite permet de définir des méthodes (abstraites ou non) qui seront utilisées par d'autres classes, méthodes qui seront communes et/ou spécifiques à ces sous classes. Si la méthode est commune, on la définit et l'implémente dans la classe abstraite; si elle est spécifique, on la définit dans la classe abstraite et on l'implémente dans la sous classe. C'est ça ?
    C'est bien l'impression que ca donnait. La factorisation est un avantage de l'objet. Mais ce n'est pas le plus important. Quand on regarde tes exemples, les méthodes abstraites ne sont jamais appelées en utilisant la classe abstraite. Elles sont donc inutiles.
    Le plus important, c'est le polymorphisme. C'est à dire le fait qu'il est possible d'ecrire et d'utiliser des classes ayant un comportement commun, meme si elles ne sont pas encore écrites.

    Prenons un exemple. Tu fais un jeu d'echec. Imaginons une classe IA qui gere l'IA de l'ordi. Ca donnera un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public abstract class IA
    {
    .... code commun aux IA
     
    public abstract Move getNextMove();
    }
    qui sera utilisée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void play(IA ia)
    {
    ...
     
    Move nextMove = ia.getNextMove();
    doMove(nextMove);
    }
    Puis une classe qui l'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class IANulle
    {
    ...
     
      public Move getNextMove()
      {
         Move nextMove;
         // Comme on fait une IA nulle, on peut faire un mouvement aleatoire.
         ...
         return nextMove;
      }
    }
    En faisant ca, on peut faire le jeu sans avoir fait l'IA. Mieux, on peut créer différentes IA de différents niveaux et le fait d'appeler la fonction play avec une IA (en faisant play(new IANulle());) ou une autre changera la maniere de jouer de l'ordinateur. Et tout ca en changeant simplement l'appel à play et sans toucher au contenu de cette fonction.

  13. #13
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Je pensais pas que j'aurai autant de mal avec cette partie là

    - Dans ton code 1, tu crées la classe abstraite IA (et tu récupères la méthode NextMove de la classe Move ?)
    - Dans ton code 2, à quoi correspond le "ia" ? Et pourquoi faire le doMove(nextMove) si tu ne l'utilises pas ailleurs ? C'est juste pour l'exemple ici ?

    Je pense avoir cerner le principe mais c'est la mise en application qui a du mal.
    En fait mes exemples sont bof bof car c'est le problème du comment faire référence aux méthodes déclarées, non ?

  14. #14
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par devdav Voir le message
    Je pensais pas que j'aurai autant de mal avec cette partie là
    C'est la partie la plus intéressante de la programmation orientée objet Donc celle a bien maitriser

    Citation Envoyé par devdav Voir le message
    - Dans ton code 1, tu crées la classe abstraite IA (et tu récupères la méthode NextMove de la classe Move ?)
    Pour éviter d'embrouiller, j'ai essayé de mettre le minimum de code sans rapport avec le polymorphisme. Dans mon exemple, Move est un objet qui représente le mouvement d'une piece. Donc IA est la classe qui doit déterminer quelle piece l'ordinateur doit bouger et ou. C'est pour ca que la classe IA possède une méthode getNextMove qui renvoie un objet Move.

    Citation Envoyé par devdav Voir le message
    - Dans ton code 2, à quoi correspond le "ia" ? Et pourquoi faire le doMove(nextMove) si tu ne l'utilises pas ailleurs ? C'est juste pour l'exemple ici ?
    Pareil, ca, c'est parce que doMove n'est pas une méthode qui nous interesse pour le polymorphisme. Elle va simplement, avec l'objet Move qu'a renvoyé l'IA faire bouger la piece à l'ecran pour afficher à l'utilisateur le mouvement de l'IA.

    Citation Envoyé par devdav Voir le message
    Je pense avoir cerner le principe mais c'est la mise en application qui a du mal.
    En fait mes exemples sont bof bof car c'est le problème du comment faire référence aux méthodes déclarées, non ?
    C'est surtout que tu n'utilises pas la classe abstraite autrement que comme un conteneur de code/variables pour les classes filles. Encore une fois, ce n'est qu'un aspect de l'héritage et pas le plus interessant. Ce qu'il faut comprendre, c'est surtout l'aspect polymorphisme.

  15. #15
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Je vais plancher là dessus alors, ça a quand même l'air intéressant, comme tu dis
    Avec tous tes exemples, je vais bien arriver à en tirer quelque chose !

    Merci beaucoup pour ton aide, c'est bien d'avoir un suivi comme ça.
    Je reviendrai probablement rapidement pour dire comment j'ai avancé; ravis si tu sera encore là

  16. #16
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 42
    Par défaut
    Re bonjour,

    bon décidément j'ai du mal avec ce maudit polymorphisme et ces classes abstraites.
    Est-ce que, avec ce programme, j'utilise correctement ces fonctions de la POO ?
    (Je sais qu'il faut que je fasse attention avec les protected mais pour l'instant laissons ça de côté svp)

    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
    public class Main {
    	public static void main (String [] args){
     
    		Roman r = new Roman("L'eau de rose", "Jean ROCH", 200, 2013);
    		r.ranger();
    		r.bruler();
    		r.consulter();
    		r.jeter();
    		r.vendre();
    		System.out.println("\n");
     
    		People m = new People("Rihanna", "Pauline M", "Presse", 2011);
    		m.ranger();
    		m.bruler();
    		m.consulter();
    		m.jeter();
    		m.vendre();	
    	}
    }
    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
    abstract class Oeuvres {
     
    	protected String nom, auteur;
    	protected int nbPages;
     
    	// on range dans des categories differentes
    	abstract void ranger();
    	// on peut vendre n'importe quelle oeuvre
    	void vendre(){
    		System.out.println("On vend une oeuvre");
    	}
    	// on peut consulter n'importe quelle oeuvre
    	void consulter(){
    		System.out.println("On consulte une oeuvre");
    	}
    	// on ne jete pas n'importe quelle oeuvre n'importe où
    	abstract void jeter();
     
    	// on ne brule pas n'importe quelle oeuvre
    	abstract void bruler();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    abstract class Livre extends Oeuvres {
    	protected String année;
     
    	void jeter(){
    		System.out.println("On jette dans le conteneur Livre");
    	}
    	void bruler(){
    		System.out.println("On peut les bruler");
    	}
    }
    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 Roman extends Livre {
    	private int année;
    	public Roman (String pNom, String pAuteur, int pNbPages, int pAnnée){
    		nom=pNom;
    		auteur=pAuteur;
    		nbPages=pNbPages;
    		année=pAnnée;
     
    		System.out.println("Nom: "+nom+"\n"+"Auteur: "+auteur+"\n"+"Nb Pages: "+nbPages+"\n"
    				+"Année: "+année);
    	}
    	void ranger (){
    		System.out.println("On le range dans les romans");
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    abstract class Magazines extends Oeuvres {
    	protected String nom, auteur, theme;
    	protected int année;
     
    	void jeter(){
    		System.out.println("On les jette dans le conteneur magazines");
    	}
    	void bruler(){
    		System.out.println("On ne peut pas les bruler");
    	}
    }
    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 class People extends Magazines{
    	public People (String pNom, String pAuteur, String pTheme, int pAnnée){
    		nom=pNom;
    		auteur=pAuteur;
    		theme=pTheme;
    		année=pAnnée;
     
    		System.out.println("Nom: "+nom+"\n"+"Auteur: "+auteur+"\n"+"Theme: "+theme+"\n"
    				+"Année: "+année);
    	}
    	void ranger(){
    		System.out.println("On le range dans People");
    	}
    }

  17. #17
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par devdav Voir le message
    bon décidément j'ai du mal avec ce maudit polymorphisme et ces classes abstraites.
    Est-ce que, avec ce programme, j'utilise correctement ces fonctions de la POO ?
    (Je sais qu'il faut que je fasse attention avec les protected mais pour l'instant laissons ça de côté svp)
    Correctement, oui. Mais de maniere utile, non. D'ailleurs, pour t'en convaincre, il suffit de supprimer les fonctions "ranger" et "bruler", par exemple, de ta classe Oeuvre et tu verras que ca marche quand meme. Pour que ce soit interessant, il faudrait manipuler des variables de type Oeuvre. Tant que tu ne fais pas ca, le seul interet de tes classes abstraites est de factoriser du code.

    Bon, pour t'aider à mieux voir, on va parler d'un exemple concret.
    Imagine que tu veuilles manipuler des données. Celles-ci peuvent venir de différentes sources : un utilisateur qui tape dans un Edit box, un fichier sur l'ordinateur, un fichier sur internet... On imagine que tu cherches à compter le nombre de caracteres 'a'.
    Pour gérer tous ces cas, l'idée va etre de créer une classe abstraite ou une interface avec la fonction public char read() qui permet de renvoyer le caractere suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public interface ReadSource
    {
      /**
        * Renvoie le prochain caractere lu et -1 si fin du fichier
        */
      int read() throws IOException;
    }
    Ensuite, tu vas compter le nombre de caracteres 'a' :
    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 int compte(ReadSource rs)
    {
      int nb = 0;
      int c;
      while((c = rs.read()) != -1)
      {
        if ((char)c == 'a')
        {
          nb++;
        }
      }
     
      return nb;
    }
    Maintenant, il suffit de créer une classe qui implémente ReadSource et tu peux utiliser un fichier, une base de données ou ce que tu veux. Par exemple, pour lire un fichier, on peut utiliser la classe FileReader. Et, coup de bol, elle definit deja la fonction read qui est définie dans l'interface InputStream :
    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
    public class FileSource extends FileReader implements ReadSource
    {
      public FileSource(String fileName)
      {
        super(fileName);
      }
     
      /**
       * Il n'est pas nécessaire de redefinir cette fonction puisque read est deja
       * défini dans FileReader et fait ce qu'on veut.
       * Mais bon, c'est surtout pour te faire remarquer qu'elle existe.
       */
      public int read() throws IOException
      {
        return super.read();
      }
    }
    A partir de la, on peut appeler la fonction compte avec notre classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MaClasse c = new MaClasse();
    s.compte(new FileSource("c:\\test.txt"));
    Et il suffirait d'utiliser une autre classe qui lit les entrées utilisateur et qui implemente ReadSource pour pouvoir utiliser compte avec.

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/04/2012, 16h11
  2. Question sur les classes abstraites
    Par zpico dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 23/05/2011, 16h15
  3. [Debutant][Conception] Classes abstraites et interface.
    Par SirDarken dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 00h02
  4. Classe abstraite / MVC
    Par caramel dans le forum MVC
    Réponses: 5
    Dernier message: 01/04/2003, 09h27
  5. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 19h02

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