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 :

[POO] Besoin d'éclaircissements.


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Par défaut [POO] Besoin d'éclaircissements.
    Bonjour,

    Je me pose une question à propos de quelque chose que je vois très souvent en Java, et je voudrais savoir si c'est parce que c'est java ou parce que c'est la poo.

    On a une classe abstraite A, et une classe B qui hérite de A.

    Très souvent donc, on trouvera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    A maclasse = new B();
    Pour quelle raison fait-on ça ?

    Il est très probable que B contienne des méthodes qui ne sont pas dans A, et donc déclarer maclasse comme ça ne permet pas d'utiliser ces méthodes.

    Sauf si on caste maclasse en B, ce qui du coup devient franchement n'importe quoi.

    L'abstraction, d'apres moi, c'est très bien quand justement on veut généraliser. Par exemple, s'il y a 20 classes qui héritent de A, et qu'on veut dans une fonction juste appeller une méthode qui est déjà dans A, on a, à ce moment là, pas besoin de savoir quelle classe c'est.

    Par contre instancier volontairement une classe en se privant de ses membres, je ne vois pas l'astuce.

    Donc, vu que j'ai probablement mal compris l'idée générale, si une bonne âme pouvait m'éclairer, je lui en serait reconnaissant.

    Merci

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Pour rendre l'exemple plus clair, il suffit d'imaginer que plusieurs classes étendent A, donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class B extends A
    class C extends A
    etc...
    Maintenant, imagine qu'on veuille traiter un liste d'objets B, C, ... par leur fonctionnalités A (issues de A)
    On peut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (A item : listeDeBC)
    {
       item.fonctionDeA();
    }
    C'est "un peu" le même principe qu'avec une interface...

    J'espère avoir été assez clair...
    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Pour rendre l'exemple plus clair, il suffit d'imaginer que plusieurs classes étendent A, donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class B extends A
    class C extends A
    etc...
    Maintenant, imagine qu'on veuille traiter un liste d'objets B, C, ... par leur fonctionnalités A (issues de A)
    On peut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (A item : listeDeBC)
    {
       item.fonctionDeA();
    }
    C'est "un peu" le même principe qu'avec une interface...

    J'espère avoir été assez clair...
    A+
    En fait c'est pas du tout ça.

    Dans ton exemple, c'est de l'abstraction, pour généraliser une action, parce que tu n'utilises qu'une fonction qui est décrite dans la classe mère ou dans l'interface. Et c'est l'utilisation évidente.

    Mon problème à moi, c'est quand on trouve des trucs comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    List<A> list = new ArrayList<A>();
    etc..

    Du coup, list n'aura accès qu'aux méthodes de List, mais pas de ArrayList.

    Donc je vois pas l'interet.

  4. #4
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    Citation Envoyé par Faiche Voir le message
    Mon problème à moi, c'est quand on trouve des trucs comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    List<A> list = new ArrayList<A>();
    etc..

    Du coup, list n'aura accès qu'aux méthodes de List, mais pas de ArrayList.

    Donc je vois pas l'interet.
    L'intérêt est de ne être dépendant de ArrayList, et de se laisser la possibilité d'utiliser éventuellement quelque chose de plus optimisé ou de plus approprié.

  5. #5
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    Citation Envoyé par Faiche
    L'abstraction, d'apres moi, c'est très bien quand justement on veut généraliser. Par exemple, s'il y a 20 classes qui héritent de A, et qu'on veut dans une fonction juste appeller une méthode qui est déjà dans A, on a, à ce moment là, pas besoin de savoir quelle classe c'est.
    A priori tu as très bien compris le pourquoi du comment.
    C'est juste qu'on sait qu'on a un véhicule, et qu'on veut le faire avancer, reculer, tourner, freiner, peu importe que ce soit une moto, un quad, une voiture ou un camion.
    La seule contrainte, c'est qu'il faut que la classe hérite d'une classe particulière.
    Et si tu veux aller plus loin, et que tu ne veux pas cette contrainte, et bien on utilise une interface.
    On sait pas qui c'est, mais il doit remplir le contrat, l'interface.
    Cela permet d'étendre des implémentations possibles d'un même contrat.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Petit aujout pour le cas des interfaces :

    Dans 98% des cas je déclare mes collections/maps comme celà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Collection c = new LinkedHashSet();
    Derrière tu ne manipules plus que l'interface Collection, tu brises ainsi la dépendance directe que tu as avec l'implémentation "LinkedHashSet". Si demain tu veux que ta collection soit automatiquement triée, tu modifies la déclaration LinkedHashSet en TreeSet et le tour est joué !

  7. #7
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Par défaut
    Citation Envoyé par Duc Lebowski Voir le message
    Petit aujout pour le cas des interfaces :

    Dans 98% des cas je déclare mes collections/maps comme celà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Collection c = new LinkedHashSet();
    Derrière tu ne manipules plus que l'interface Collection, tu brises ainsi la dépendance directe que tu as avec l'implémentation "LinkedHashSet". Si demain tu veux que ta collection soit automatiquement triée, tu modifies la déclaration LinkedHashSet en TreeSet et le tour est joué !
    Bon, jusque la j'avais bien compris que comme ça, on sait pas du tout si on utilise un linkedhashset ou va savoir quoi.

    Maintenant, t'as dans les mains une collection, et tu veux utiliser une méthode qui est spécifique a linkedhashset, tu fais quoi ?

  8. #8
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    Citation Envoyé par Faiche Voir le message
    Maintenant, t'as dans les mains une collection, et tu veux utiliser une méthode qui est spécifique a linkedhashset, tu fais quoi ?
    Soit tu es cohérent, et tu n'as qu'une collection, point barre.
    Soit tu test que c'est bien une classe spécifique que tu connais, et là si c'est nécessaire, tu peux utiliser une fonctionnalité particulière. Mais il faut éviter les castages sauvages...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 41
    Par défaut
    bonjour,

    effectivement il peut y avoir une utilité à utiliser le polymorphisme de cette façon encore un exemple :

    http://abrillant.developpez.com/tuto...oduction/#L3.1

    Je vais déclarer tous mes objet en Object maintenant :p

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Depuis 5 ans que je développe en Java, je crois que je n'ai jamais eut à appliquer une méthode spécifique sur une implémentation de Collection...

    Par défaut je manipule toujours l'interface. Si demain je dois appeler une méthode spécifique alors je reverrai ma conception.

    Et puis c'est le principe d'inversion des dépendances (DIP) :

    A. Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau. Tous deux doivent dépendre d'abstractions.

    B. Les abstractions ne doivent pas dépendre de détails. Les détails doivent dépendre d'abstractions.

    Vas faire un petit tour ici, tout est dit !

  11. #11
    Membre éclairé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Par défaut
    Ok.

    Bon, je comprends l'idée du coup.

    Je vais déclarer tous mes objet en Object maintenant :p

    Enfin bon, merci pour l'explication

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

    Citation Envoyé par Faiche Voir le message
    Maintenant, t'as dans les mains une collection, et tu veux utiliser une méthode qui est spécifique a linkedhashset, tu fais quoi ?
    Dans 99% des cas tu te contentes des méthodes décrites dans l'interface que tu utilises. Pour info il ne me semble pas que LinkedHashSet propose des méthodes supplémentaires, mais ta question n'en est pas quand même très pertinente...

    Parfois l'abstraction systématique peut en effet être abusive, en particulier dans la déclaration d'un variable (j'y reviendrais un peu plus loin), mais lors de l'utilisation d'un paramètre de méthode ou de son type de retour.


    Imaginons une méthode qui permette de calculer le prix d'une liste de produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public double calculerPrixTotal(ArrayList<Produit> listeProduits) {
    	double montant = 0.0;
    	for (Produit p : listeProduits) {
    		montant += p.getQuantite() * p.getPrix();
    	}
    	return montant;
    }
    Rien de bien compliqué, mais comme elle utilise une ArrayList ta méthode a un gros défaut : elle se limite justement aux ArrayList !

    Si pour une raison X ou Y je dois utiliser un autre type de collection (par exemple une LinkedHashSet), je ne pourrais plus utiliser ta méthode directement et je devrais passé par une collection intermédiaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    LinkedHashSet<Produit> set = ...;
     
    double prix = calculerPrixTotal( new ArrayList<Produit>(set) );
    Ce qui est non seulement pas très pratique, mais provoque également une duplication inutile...

    Dans cet exemple la méthode calculerPrixTotal() utilise abusivement le type ArrayList, car elle attend simplement une liste de produit quelquonque, et devrait donc utiliser plutôt une Collection : après tout pour faire une somme quel intérêt y a t-il de savoir avec précision comment sont "rangés" les produits, du moment qu'on peut les lister...

    Mieux, avec Java 5.0 on pourrait se contenter d'utiliser Iterable qui décrit simplement la méthode iterator() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public double calculerPrixTotal(Iterable<Produit> listeProduits) {
    	double montant = 0.0;
    	for (Produit p : listeProduits) {
    		montant += p.getQuantite() * p.getPrix();
    	}
    	return montant;
    }
    Désormais notre méthode calculerPrixTotal() est générique et peut être utilisée avec n'importe quel type de collection d'objet...







    Maintenant il y a certains cas où cette abstraction peut être abusive, justement dans le cadre d'une variable locale où on est plus proche.

    Prenons le cas de la méthode suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public List<Produit> creerListeProduit() {
    	List<Produit> list = new ArrayList<Produit>();
     
    	// Récupération de la liste des produits (depuis une BD, un fichier, etc...
    	while (...) {
    		list.add(produit);
    	}
     
    	return list;
    }
    Le code est bien générique puisqu'on utilise List en type de retour et non pas ArrayList, mais en interne il serait intérressant d'utiliser une ArrayList. En effet les ArrayList utilise un tableau pour stocker les valeurs, et ce dernier est doublé à chaque fois qu'il est "plein", et possède donc un certain nombre d'emplacement 'inutile' en particulier si la liste ne sera plus modifié par la suite.

    On peut corriger cela en utilisant la méthode trimToSize() spécifique aux ArrayList, mais il faut conserver son type dans la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public List<Produit> creerListeProduit() {
    	ArrayList<Produit> list = new ArrayList<Produit>();
     
    	// Récupération de la liste des produits (depuis une BD, un fichier, etc...
    	while (...) {
    		list.add(produit);
    	}
     
    	// On 'élimine' les emplacements inutiles :
    	list.trimToSize();
     
    	return list;
    }



    Bref : en interne on peut avoir besoin de connaitre le type précis afin d'utiliser certaines de ses spécificités, mais dans 99% des cas on se fiche pas mal de son implémentation et il est préférable d'utiliser un des types de base pour une plus grande généricité...


    Maintenant, dans le doute il faut priviliéger l'abstraction car il y a bien moins de conséquence dans le fait de changer le type d'une variable locales que de modifier les types des paramètres et valeur de retour de méthodes public (cela provoque une incompatibilité).


    a++


    PS : comme d'hab j'ai fait un gros pavé et le sujet est résolu

  13. #13
    Membre émérite
    Avatar de neilbgr
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2004
    Messages
    651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 651
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    PS : comme d'hab j'ai fait un gros pavé et le sujet est résolu
    c'est pas grave, y a eu des réponses abstraites et la tienne est concrète.

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

Discussions similaires

  1. [POO] Besoin d'éclaircissement
    Par mik3.42 dans le forum WinDev
    Réponses: 9
    Dernier message: 26/06/2009, 08h59
  2. [vb6] traitement d'images, besoin d'éclaircissements
    Par Asdorve dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 01/08/2006, 10h20
  3. [JGoodies] besoin d'éclaircissements
    Par sozie9372 dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 26/06/2006, 23h10
  4. [POO] Besoin de tutorat sur les classes
    Par misterniark dans le forum Langage
    Réponses: 11
    Dernier message: 20/04/2006, 13h48
  5. Réponses: 15
    Dernier message: 29/12/2005, 10h32

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