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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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.

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, 14h43
  2. [Info] Est-ce bien du J2EE ?
    Par LESOLEIL dans le forum Java EE
    Réponses: 6
    Dernier message: 21/02/2006, 10h54
  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, 21h31
  4. Réponses: 9
    Dernier message: 04/10/2005, 13h50
  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, 12h41

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