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 :

[INTERFACE] Le concept est-il bien maitrisé ?


Sujet :

Langage Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 17
    Par défaut [INTERFACE] Le concept est-il bien maitrisé ?
    Bonsoir à tous,

    Je viens du monde C++ et j'ai récemment étudié d'autres langages qui utilisent la notion dont Java

    Après avoir lu la FAQ Java ainsi que plusieurs sites,
    J'ai tout d'abord compris cette notion (d'interface) comme étant un moyen de réunir plusieurs classes indépendantes (Ex : Homme et Felin) comme presenté ici : http://www.developpez.net/forums/d63...et-interfaces/
    On factorise un comportement commun à des classes de différents types par le biais d'une interface.

    Cependant, j'observe souvent l'utilisation des interfaces comme une relation d'héritage "is-a". Or, pour cette relation, on utilise normalement naturellement l'héritage classique (extends)

    Au delà de la factorisation des comportements de classes différentes et de l'obligation d'adherer au contrat lorsqu'on implémente une interface, quels sont les autres utilités de l'interface.


    Merci d'avance pour vos informations

  2. #2
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Une interface est un contrat.
    Une classe implémentant une interface s'engage à respecter ce contrat.

    Elle n'est pas du tout là pour associer des classes qui n'ont rien à voir.

    Exemple:

    On peut dire qu'un chat peut bouger et qu'un poisson aussi. Cependant, ils ne bougent pas de la même manière. Le chat va "marcher" et le poisson va "nager".
    Ce sont des détails que la classe qui cherche à faire bouger cette entité n'a pas besoin de savoir.

    Imaginons 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    class Chat {
    	public void marche() {
    		System.out.println("Le chat commence à marcher...");
    	}
     
    	public void arreteDeMarcher() {
    		System.out.println("Le chat s'arrête de marcher...");
    	}
    }
     
    class Poisson {
    	public void nage() {
    		System.out.println("Le poisson commence à nager...");
    	}
     
    	public void arreteDeNager() {
    		System.out.println("Le poisson s'arrête de nager...");
    	}
    }
     
    public class MaClasse {
    	protected List< Chat > mesChats;
    	protected List< Poisson > mesPoissons;
     
    	public MaClasse() {
    		mesChats = new LinkedList< Chat >();
    		mesPoissons = new LinkedList< Poisson >();
    	}
     
    	public void travail() {
    		for( Chat c : mesChats ) {
    			c.marche();
    		}
     
    		for( Poisson p : mesPoissons ) {
    			p.nage();
    		}
    	}
     
    	public void stop() {
    		for( Chat c : mesChats ) {
    			c.arreteDeMarcher();
    		}
     
    		for( Poisson p : mesPoissons ) {
    			p.arreteDeNager();
    		}
    	}
    }
    Tu vois qu'il y a de la redondance, peu importe le type d'animal, on effectue certaines taches "dont la sémantique est la même".

    On peut ré-écrire le code comme ceci, et tout devient plus clair:

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    interface Deplacable {
    	public void avance();
    	public void arrete();
    }
     
    class Chat implements Deplacable {
     
    	public void avance() {
    		System.out.println("Le chat commence à marcher...");
    	}
     
    	public void arrete() {
    		System.out.println("Le chat s'arrête de marcher...");
    	}
    }
     
    class Poisson implements Deplacable {
    	public void avance() {
    		System.out.println("Le poisson commence à nager...");
    	}
     
    	public void arrete() {
    		System.out.println("Le poisson s'arrête de nager...");
    	}
    }
     
    public class MaClasse {
    	protected List< Deplacable > mesAnimaux;
     
    	public MaClasse() {
    		mesChats = new LinkedList< Deplacable >();
    		mesChats.add( new Chat() );
    		mesChats.add( new Poisson() );
    		//...
    	}
     
    	public void travail() {
    		for( Deplacable d : mesAnimaux ) {
    			d.avance();
    		}
    	}
     
    	public void stop() {
    		for( Deplacable d : mesAnimaux ) {
    			d.arrete();
    		}
    	}
    }
    Ici, l'interface Deplacable définit un contrat: la classe qui l'implémente admet qu'elle peut avancer et s'arrêter. Le comportement doit être bien définit.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 17
    Par défaut
    Bonsoir Julien et merci pour ta réponse. Je suis d'accord avec ce que tu viens d'écrire. Poisson et Chat sont des animaux mais il n'appartiennent pas à la même "branche".

    Si on prend l'exemple de Java. Lorsqu'on implémente l'interface Runnable, que ca soit sur un traitement sur un fichier(classe FichierTextProcessing qui implémente Runnable) ou sur un serveur qui écoute(classe ServeurJeu qui implémente Runnable) les deux n'ont rien à voir cad ne sont pas liés par un ancêtre commun(en terme d'héritage). Pourtant ces deux classes sont traités de la même façon lorsqu'on lance les Thread (start() sur les deux)

    En partant de cet exemple, existe-t-il une autre utilité pour les interfaces ?

  4. #4
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Je te l'ai déjà dit, 2 classes qui n'ont rien avoir peuvent implémenter une interface sans être associées.

    Pour rebondir sur ce que tu avais dit:
    Citation Envoyé par Blowdi
    [interface] un moyen de réunir plusieurs classes indépendantes
    L'interface Runnable décrit un contrat que doit respecter une classe étant destinée à être un thread. Toute classe qui implémente Runnable peut donc être manipulée par l'API Java pour être traitée comme tel.

    Les interfaces sont très importantes car elles décrivent ce que tu peux faire et ne pas faire avec une classe.

  5. #5
    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
    L'intérêt principal de l'interface est dans le polymorphisme implicite qu'elles apportent.
    Les classes peuvent être vues sous forme de l'interface plutôt que sous la forme de la classe réelle.
    Ainsi, une voiture ou un bateau implémentant l'interface "SeDeplace" peuvent être traités par un "contrôleur" (pour l'exemple) 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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    interface SeDeplace
    {
       public void avance();
       public void recule();
       public Point getPosition();
    }
     
    class Voiture implements SeDeplace
    {
       public void avance()
       {
          ... traitement spécifique
       }
       public void recule()
       {
          ... traitement spécifique
       }
       public Point getPosition()
       {
          ...
       }
    }
     
    class Bateau implements SeDeplace
    {
       public void avance()
       {
          ... traitement spécifique
       }
       public void recule()
        {
           ... traitement spécifique
        }
       public Point getPosition()
       {
          ...
       }
    }
     
    class Controleur
    {
       private List<SeDeplace> list = new ArrayList<SeDeplace>();
     
       public Controleur()
       {
           list.add(new Voiture());
           list.add(new Bateau());
       }
     
       public void process()
       {
          for (SeDeplace obj : list)
          {
             if (obj.getPosition() ...)
             {
                ...
             }
          }
       }
    }
    C'est beaucoup plus simple et dynamique que de passer par les types d'objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    if (obj instanceof Voiture)
    {
       Voiture v = (Voiture)obj;
    }
    else
    {
       if (obj instancof Bateau)
       {
          Bateau b = (Bateau)obj;
       }
    }
    ...
    Là, il faudrait par avance connaître tous les types et la liste pourrait être alimentée par un autre process...

    Avec les interfaces, on peut ajouter autant de types d'objets implémentant "SeDeplace" qu'on veut sans avoir à toucher à la classe Controleur

    Tu comprends ce que je veux dire ou je ne suis pas clair ?

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 15
    Par défaut
    Il est vrai que la principale utilité d'une interface Java est la possibilité de mettre en place des contrats. C'est cet aspect que j'utilise principalement dans mes programmes. De cet façon, je peux conserver une certaine généricité de mon code. De plus les interfaces facilitent la mise en place de patterns tels que Loose Coupling (couplage lâche), Dependecy Injection, Inversion Of Control, très prisées en ce moment (voir Spring). Les interfaces permettent la mise en place de SPI (Service Provider Interface, voir wikipedia), si j'associe mes interfaces avec des classes abstraites.

    Par contre, une interface ne permet pas explicitement de factoriser un comportement.

    Autre point, si une classe ne peut hérité de plusieurs autres classes (extends), une classe peut implémenter plusieurs interfaces.

    Une autre utilité reconnue des interfaces est d'utiliser une interface en tant que marqueur. Par exemple, l'interface Serializable ne présente aucune signature de méthode. Elle est là pour indiquer que les instances d'une classe donnée peuvent être transférer sur un flux. Ce rôle de marqueur est aussi en partie le rôle des interfaces telles que Runnable, Comparable, Clonable, etc. (tout ce qui se termine par -able, par convention). Toutefois, ce rôle de marqueur a été transférer depuis Java 5 aux annotations, qui offrent une plus grande flexibilité dans ce cadre.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Citation Envoyé par kerflyn Voir le message
    Par contre, une interface ne permet pas explicitement de factoriser un comportement.
    C'est là typiquement le rôle des classes abstraites.

  8. #8
    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
    Citation Envoyé par dingoth Voir le message
    C'est là typiquement le rôle des classes abstraites.
    ou pas abstraites...

    La classe n'a pas besoin d'être abstraite pour être étendue
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Bien sûr, mais c'est essentiellement l'utilité des classes abstraites, sans que cela soit leur exclusivité.

  10. #10
    Membre Expert

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Par défaut
    Citation Envoyé par kerflyn Voir le message
    Ce rôle de marqueur est aussi en partie le rôle des interfaces telles que Runnable, Comparable, Clonable, etc. (tout ce qui se termine par -able, par convention).
    Pour Serializable je suis d'accord, mais pour les autres quand même ... elles définissent un contrat.

  11. #11
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Moi aussi je viens du monde C++, une interface est une classe virtuelle pure (contenant que des fonctions membres sans implémentation (method() = 0) et éventuellement des constantes)
    Une interface est un contrat, c'est un type qui définie les opérations à faire sans qu'il est une existence propres en soit càd aucun object (instances en mémoire) n'est réellement de type interface, ex : les nombres peut être représenté par une interface mais un nombre est soit entier, réel, Complexe..etc
    Voilà j'espère que ça t'a éclairict les choses..
    A++

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    On préfèrera toutefois éviter d'utiliser des interfaces afin de définir des constantes en Java même si c'est possible.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par dingoth Voir le message
    On préfèrera toutefois éviter d'utiliser des interfaces afin de définir des constantes en Java même si c'est possible.
    Pour compléter ta phrase:
    Les enum sont beaucoup plus appropriés pour ça dans la plus part des cas

    Pour prendre un autre exemple concret de l'utilisation des interface. L'API swing (GUI) a énormément besoin de "callback" pour appeler des bout de code quand on clique à gauche et à droite (Quand je clique sur le menu xyz, ca doit appeler tel bout de code, sur aun autre menu un autre bout de code, etc). Les callback à la C / C++ ça n'existe pas en java, car les pointeurs sur les méthodes n'existent pas. On prèfère utiliser les interfaces. On va donc passer au menu une implémentation d'un "ActionListener", interface définissant ce que le menu peux faire de l'action (en l'occurence appeler sa méthode 'actionPerformed' en lui passant en argument un ActionEvent). Et c'est dans cette méthode que l'on mettre le bout de code qui nous concerne. Maintenant, le "menu" n'a pas besoin de savoir sir l'action Performed est implémenter au sein d'un JFrame, au sein d'un JPanel, au sein d'un Thread ou au sein d'un objet quelconque. Il a juste besoin de savoir que ce qu'on lui passe "implémente l'interface ActionListener". Ce qu'il ferais éventuellement en plus, c'est pas ses oignons

  14. #14
    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
    Citation Envoyé par tchize_ Voir le message
    Pour compléter ta phrase:
    Les enum sont beaucoup plus appropriés pour ça dans la plus part des cas
    Pour compléter également

    Les propriétés static d'une classe (Abstraite ou pas) me semble également très bien placées quand il ne s'agit pas de type énuméré...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Citation Envoyé par dingoth Voir le message
    On préfèrera toutefois éviter d'utiliser des interfaces afin de définir des constantes en Java même si c'est possible.
    Je n'ai jamais dit que c'était préférable d'utiliser des constantes à l'intérieure d'une interface j'explique juste ce que contient une interface et si les constance sont autorisées (une variable static final) car elle ne dépend d'aucune instance du coup si on fait un héritage multiple de plusieurs interfaces on hérite d'aucune propriété (variable membre) puisqu'il y on a pas du coup on a pas de problème d'héritage multiple (héritage en diamant)

  16. #16
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Je n'ai jamais dit que tu l'avais dit non plus : j'ajoutais une précision quant au rôle d'une interface dans une application bien designée

Discussions similaires

  1. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 15h43
  2. [Info] Est-ce bien du J2EE ?
    Par LESOLEIL dans le forum Java EE
    Réponses: 6
    Dernier message: 21/02/2006, 11h54
  3. [CONTEXT_FILETXT] Est-ce bien pour faire un menu contextuel
    Par Furius dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 18/11/2005, 22h31
  4. Réponses: 9
    Dernier message: 04/10/2005, 14h50
  5. Est ce bien la meilleure façon de faire un histogramme ?
    Par rvzip64 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 10/05/2005, 13h41

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