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 :

Classes Abstraites et Interfaces


Sujet :

Langage Java

  1. #1
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    342
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 342
    Points : 161
    Points
    161
    Par défaut Classes Abstraites et Interfaces
    contrairement aux questions qui surgisses sur ces deux termes, je voudrais avouer que moi je comprends parfaitement la différence entre les deux ainsi que leurs avantages en ce qui concerne le polymorphisme et la factorisation du code. Mes questions sont les suivantes :

    1) Tout ce que je fais avec une classe abstraite, je le fais avec une classe simple que je décide de ne pas instancier et là donc je me demande l'importance du mot clé Abstract... si ce n'est laisser le refus de l'instanciation au compilateur ?

    2) En dehors du faite que je peux déclarer des constantes 'globale' dans mon interface et en bénéficier dans tout le code, du fait qu'une classe peut implémenter plusieurs interfaces et enfin à cause du polymorphisme, Je ne vois pas leur importance quant-à 'non-répétition du code

    Exemple :

    Soit une interface Int1 ayant une méthode M1 et 50 classes : Class1, Class2 et Class3....Class50 qui implémentent cette méthode.
    Si demain je me rends compte dans ma conception qu'une seconde méthode améliorerai l'application que ferais-je ?
    Je sais que je peux créer une seconde interface Int2 avec la méthode M2 et je choisirais soit de faire pour éviter d'implémenter cette méthode dans mes 50 classes parce que même si je crée une deuxième Interface, ça n'enlèvera pas le fait que j'ai besoin de cette méthode te je dois l'implémenter, donc autant mieux l'ajouter simplement dans la première Interface et l'implémenter partout.

    3) Quelqu'un a-t-il une idée comment faire pour éviter d'implémenter cette méthode 50 fois, si possible le faire une seul fois en établir un lien avec les autres 50 classes.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par mesken Voir le message
    1) Tout ce que je fais avec une classe abstraite, je le fais avec une classe simple que je décide de ne pas instancier et là donc je me demande l'importance du mot clé Abstract... si ce n'est laisser le refus de l'instanciation au compilateur ?
    Ca n'a en général pas trop d'intéret de déclarer abstract un classe qui n'a aucune méthode abstraite, car elle est utilisable en l'état

    2) En dehors du faite que je peux déclarer des constantes 'globale' dans mon interface et en bénéficier dans tout le code, du fait qu'une classe peut implémenter plusieurs interfaces et enfin à cause du polymorphisme, Je ne vois pas leur importance quant-à 'non-répétition du code
    Aucun intéret, le but et des interfaces et qu'une partie du code puisse utiliser n'importe quelle classe l'implémentant. C'est là qu'on gagne en terme de code puisqu'on ne dois pas jouer avec des 'if machin instance of truc faire ceci, sinon faire cela, ). De plus on peut implémenter plusieurs interfaces, mais étendre une seul classe.
    Si demain je me rends compte dans ma conception qu'une seconde méthode améliorerai l'application que ferais-je ?
    Dans l'état actuel des choses en java, l'implémenter 50 fois. Si cette méthode peut raisonnablement se baser sur les autres méthodes existantes, on peux faire ce genre de chose dans une classe utilitaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static boolean faireUnTruc(Int1 linterface){return linterface.a() && linterface.b();}
    et 50 fois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public boolean faireUnTruc(Int1 linterface){return utilitaire.faireUnTruc(this);}
    Cette impossibilité de fournir dans l'interface une implémentation par défaut est un réel blocage en java, sur lequel des propositions d'amélioration existent, mais qu'on ne verra pas apparaitre avant java 8. C'est d'ailleurs une des raisons qui font que l'api Collection de java n'a plus bougé depuis des années, toutes les implémentation se casseraient la gueule car elle n'implémenteraient pas les nouvelle méthodes

    Je sais que je peux créer une seconde interface Int2 avec la méthode M2
    C'est la solution apportée dans swing pour améliorer l'interface Graphics, une interface Graphics2D qui l'etend et plein de instanceof dans le code, c'est au final pas génial non plus.

  3. #3
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    342
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 342
    Points : 161
    Points
    161
    Par défaut
    Merci beaucoup tchize,

    mais le flou demeure lorsque tu dis que

    Ca n'a en général pas trop d'intéret de déclarer abstract un classe qui n'a aucune méthode abstraite, car elle est utilisable en l'état
    Je répète, même si j'ai une méthode abstraite, je peut la laisser dans cette classe sans la déclarer explicitement (Abstract...) et l'utiliser parfaitement pour faire du polymorphisme comme je veux
    Pour comprendre ma préoccupation, définis un petit programme avec une classe Abstraite et tu le compile, il marche parfaitement, après tu enlève le mot clé 'Abstract', tu te rendra compte qu'il marche toujours parfaitement
    d'où ma question "Que sert le mot clé 'Abstract' ou alors ce n'est qu'un concept ?

  4. #4
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Citation Envoyé par mesken Voir le message
    Pour comprendre ma préoccupation, définis un petit programme avec une classe Abstraite et tu le compile
    Si la classe est abstraite tu ne peux pas en créer d'instance...

  5. #5
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    342
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 342
    Points : 161
    Points
    161
    Par défaut
    Oui, herve91,
    ça je sais, c'est pourquoi je dis que je peux créer une classe normale et refuser de l'instancier...

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par mesken Voir le message
    Pour comprendre ma préoccupation, définis un petit programme avec une classe Abstraite et tu le compile, il marche parfaitement, après tu enlève le mot clé 'Abstract', tu te rendra compte qu'il marche toujours parfaitement
    Si vous retirez le mot clé abstract dans la déclaration de classe et que ça compile toujours à tous points de vue, c'est que votre classe abstraite n'a aucune méthode abstraite et donc, il n'y a aucune raison de déclarer cette classe en abstract. Vous pouvez le faire, mais ça n'a aucun intérêt. Ce que vous ne pouvez pas faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class Machin {
       public abstract void bidule(); // erreur, la classe n'est pas abstraite
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public abstract class Machin {...}
    new Machin();  // erreur, la classe est abstraite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public interface Truc{
       public void bidule();
    }
    public  class Machin implements Truc { // Erreur, doit implémenter bidule ou être abstract!
     // Rien
    }

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 553
    Points : 21 609
    Points
    21 609
    Par défaut
    Citation Envoyé par mesken Voir le message
    Oui, herve91,
    ça je sais, c'est pourquoi je dis que je peux créer une classe normale et refuser de l'instancier...
    C'est pourtant pas compliqué... Une classe abstraite a le droit d'avoir des méthodes abstraites, c'est-à-dire, déclarées, mais pas définies.
    Une classe normale n'en a pas le droit.

    Donc, avec une classe normale on est obligé d'implémenter toutes les méthodes, alors qu'avec une classe abstraite on peut laisser ça en partie aux sous-classes et n'implémenter que la logique qui leur est commune.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    package com.xyz.abc ;
     
    public class PasInstantiableEnDehorsDuPackage {
       // mais qui peut avoir des sous-classes
     
       protected PasInstantiableEnDehorsDuPackage( /* arguments */) {
           // code du constructeur qui sera appelé par super dans les sous classes
       }
    }
    variante: créer effectivement une classe abstraite sans méthode abstraite .... d'éminents auteurs (Josh. Bloch, Tchize_,...) disent que ce n'est pas pertinent , mais comme j'ai parfois des opinions bizarres je ne suis pas 100% d'accord (ce qui compte dans abstract c'est le concept lui même d'un objet qui ne peut exister en tant que tel), mais bon c'est mon avis et je le partage hein
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  9. #9
    Membre averti Avatar de _Xavier_
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2009
    Messages : 311
    Points : 390
    Points
    390
    Par défaut
    Citation Envoyé par mesken Voir le message
    Pour comprendre ma préoccupation, définis un petit programme avec une classe Abstraite et tu le compile, il marche parfaitement, après tu enlève le mot clé 'Abstract', tu te rendra compte qu'il marche toujours parfaitement
    d'où ma question "Que sert le mot clé 'Abstract' ou alors ce n'est qu'un concept ?
    Tu peux faire ce que tu veux en Java mais l'important est de respecter les concepts de base de la POO qui sont à l'origine de sa création. Tout comme les objets de la vie courante peuvent être détourner de leur usage courant.

    Les classes abstraites sont utilisées pour matérialiser des objets abstraits, qu'on ne doit pas instancier. Tu as le choix de compter sur la bonne foi des futurs utilisateurs de ton code ou leur imposer une manière de s'en servir. En cas de mauvaise manipulation les erreurs sont détectées à la compilation.

    L'interface est utilisée pour réduire les couplages (dépendances) entre les différents composants de ton application. Elle doit être l'unique porte d'entrée d'un composant, comme son nom l'indique, l'implémentation qui est plus exposée aux changements doit être cachée. Ca te permet d'avoir du code maintenable.

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Si vous retirez le mot clé abstract dans la déclaration de classe et que ça compile toujours à tous points de vue, c'est que votre classe abstraite n'a aucune méthode abstraite et donc, il n'y a aucune raison de déclarer cette classe en abstract. Vous pouvez le faire, mais ça n'a aucun intérêt.
    Si, il peut y avoir un intérêt : prenons le cas d'une librairie. Lorsque le concepteur de la librairie n'a pas imaginé qu'une classe pouvait être instanciée (parce qu'elle est utilisée à but de factorisation uniquement, par exemple), il a tout intérêt à la marquer abstract pour s'assurer que personne ne l'instanciera. De plus, cela rend l'API plus claire pour l'utilisateur de la librairie.
    Je dirais donc exactement le contraire : lorsqu'une classe n'est pas prévue pour être instanciée, c'est une bonne pratique que de la marquer abstract.

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je dirais donc exactement le contraire : lorsqu'une classe n'est pas prévue pour être instanciée, c'est une bonne pratique que de la marquer abstract.
    Là on est d'accord

    Citation Envoyé par cdefranoux Voir le message
    Si, il peut y avoir un intérêt : prenons le cas d'une librairie. Lorsque le concepteur de la librairie n'a pas imaginé qu'une classe pouvait être instanciée (parce qu'elle est utilisée à but de factorisation uniquement, par exemple), il a tout intérêt à la marquer abstract pour s'assurer que personne ne l'instanciera. De plus, cela rend l'API plus claire pour l'utilisateur de la librairie.
    La on est moins d'accord. Pourriez vous me donner un exemple d'un classe où tout a été implémenté dedans, mais où on ne veut forcer les gens à faire des sous classe? Parce que, pour moi, ça reviens à forcer les dev à écrire ce genre de code cochon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public abstract class A {
     // tout est dedans, rien d'abstrait
    }
    public class B extends A {}
    // Ben oui, A marche pour mon besoin, j'ai rien à faire donc

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 553
    Points : 21 609
    Points
    21 609
    Par défaut
    Par exemple, si A ne marche pour aucun besoin légitime a priori.

    Mais bon, normalement ça veut dire que pour répondre à un besoin légitime, les sous-classes doivent redéfinir quelque chose, et c'est mal que le compilateur ne les y oblige pas. Donc bof.

    Je verrais plutôt une classe A qui a du code commun hérité de plusieurs classes abstraites BA et BB, qui spécialisent chacune le type de A à leur manière avec de nouvelles méthodes. Et qu'il se trouve que A peut implémenter toutes ses méthodes à elle.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Je verrais plutôt une classe A qui a du code commun hérité de plusieurs classes abstraites BA et BB, qui spécialisent chacune le type de A à leur manière avec de nouvelles méthodes. Et qu'il se trouve que A peut implémenter toutes ses méthodes à elle.
    Oui et ça c'est simplement de l'héritage. La classe ne fait pas grand chose en soit, les classe BA, BB spécialisent le besoin. Ca n'a rien a voir avec les classes abstraite. Pour moi faire une classe abstraite qui n'a pas de méthode abstraite, ca sent l'erreur de design.

    Soit certaines méthode sont implémentées à vide -> Alors il aurait fallu les marquer abstraites.

    Soit toutes les méthodes sont implémentées basiquement -> Alors on ne peut préjuger d'un besoin légitime de quelqu'un de l'utiliser en l'état car elle suffira à son besoin, elle n'a donc pas a être abstraite.

  14. #14
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    . Pour moi faire une classe abstraite qui n'a pas de méthode abstraite, ca sent l'erreur de design.
    si le bon dieu l'a permis c'est que ça peut exister ....
    j'ai un exemple un peu trop compliqué pour mettre sur le forum (ça implique des tas de classes paramétrées) mais on peut en trouver d'autres (pour des raisons qu'on a le droit d'estimer limites comme HttpServlet)
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

Discussions similaires

  1. [Débutant] classe abstraite ou interface
    Par Chatbour dans le forum Langage
    Réponses: 9
    Dernier message: 29/11/2007, 09h45
  2. Difference entre Class Abstraite et interface
    Par menzlitsh dans le forum Langage
    Réponses: 11
    Dernier message: 05/07/2007, 13h04
  3. Classe abstraite et interface
    Par ender91 dans le forum Langage
    Réponses: 6
    Dernier message: 15/06/2007, 11h46
  4. Réponses: 5
    Dernier message: 28/03/2007, 17h28
  5. [Debutant][Conception] Classes abstraites et interface.
    Par SirDarken dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 00h02

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