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

C# Discussion :

[Debutant] Implémentation interface implicite et explicite


Sujet :

C#

  1. #1
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2014
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2014
    Messages : 52
    Points : 158
    Points
    158
    Par défaut [Debutant] Implémentation interface implicite et explicite
    Bonjour,

    Venant de Delphi où j'écrivais très rarement du code POO, je me converti doucement au c# avec un livre qui m'a séduit : Essential C# 6.0 que je trouve très didactique.
    J'en suis donc aux interfaces et à leurs implémentations explicites et implicites, je n'ai pas de problème à comprendre lesquelles sont appelées suivant le type d’objet mais je me pose la question peut-on implémenter d’office les deux sortes dans chaque classe ou est-ce à éviter ?

    Bonne journée.

  2. #2
    Membre expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2013
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 563
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par jenramac Voir le message
    je me pose la question peut-on implémenter d’office les deux sortes dans chaque classe ou est-ce à éviter ?
    Sauf cas particulier, implémenter les deux revient à faire de la redondance de code.. Je dirais donc que, par défaut, on implémente l'interface implicitement. Ensuite, suivant le besoin on adapte.

    [EDIT] Mais je serais curieux d'avoir l'avis d'experts (François DORIN, si tu passes par là) sur le sujet

  3. #3
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par ZenZiTone Voir le message
    Mais je serais curieux d'avoir l'avis d'experts (François DORIN, si tu passes par là) sur le sujet
    Un François sauvage fait son apparition

    Citation Envoyé par jenramac
    je me pose la question peut-on implémenter d’office les deux sortes dans chaque classe ou est-ce à éviter ?
    J'avoue que jusqu'à présent, je ne m'étais jamais posé la question. Donc déjà, implémenter les deux, c'est tout à fait possible.

    Il est possible d'éviter la redondance de code en factorisant, c'est-à-dire chaque méthode de l'interface n'est en réalité que l'appel d'une méthode privée de la classe. Ainsi, les deux interfaces sont toujours cohérentes. Car oui ! Il est possible d'implémenter deux fois une même interface dans une classe (une de manière implicite, l'autre de manière explicite), et de faire des implémentations différentes. Ce que je déconseillerais très formellement de faire vu la dangerosité de la chose !

    Maintenant, mon avis sur le sujet.
    Je déconseillerai d'implémenter d'office les deux sortes, surtout qu'une interface implémentée implicitement peut être utilisée comme une interface explicite (le contraire n'étant pas vrai).

    Les cas où j'implémente les interfaces de manières explicites sont les suivants :

    Classe implémentant plusieurs interfaces
    Ma classe implémente plusieurs interfaces, dont certaines définissent les mêmes méthodes (mais qui requiert des implémentations différentes). Dans ce cas, l'implémentation explicite d'au moins une des deux méthodes est indispensable pour lever toute ambiguïté.

    Spécialisation d'un élément
    Ma classe implémente une interface, mais spécialise un élément (disons une méthode) en "modifiant" le type de retour.
    Imaginons le modèle suivant : je suis un constructeur de moyens de locomotion et j'ai des usines qui produisent soient des avions, soit des véhicules terrestes à roues, (soit des motos, des voitures, etc...)
    Je vais donc avoir une interface IMoyenLocomotion, dont vont hériter IVehicule et IAvion

    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
     
    interface IMoyenLocomotion
    {
       bool EstAMoteur {get;}
    }
     
    interface IVoiture : IMoyenLocomotion
    {
       int NbRoues {get;}
    }
     
    interface IAvion : IMoyenLocomotion
    {
       bool EstAHelice {get;}
    }
    Maintenant, mes usines vont hérités de l'interface IUsine, qui me permet de manipuler les moyens de locomotions produits au sein de l'usine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    interface IUsine
    {
       IMoyenLocomotion RecupereParNumeroDeSerie(string numero);
    }
    Si je définie une classe MonUsineAAvion comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class MonUsineAAvion : IUsine
    {
       public IMoyenLocomotion RecupereParNumeroDeSerie(string numero)
       {
          // un peu de code ici
       }
    }
    alors mon usine à avion ne peux me retourner que des instances de IMoyenLocomotion. Mais comme c'est une usine à avion, je sais que les instances retournées implémentent aussi IAvion et je peux donc les caster pour pouvoir manipuler des avions. Mais c'est chiant, car je dois effectuer le cast.

    Maintenant, si j'utilise une implémentation explicite, je vais avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class MonUsineAAvion : IUsine
    {
       public IAvion RecupereParNumeroDeSerie(string numero)
       {
          // un peu de code ici
       }
     
       IMoyenLocomotion IUsine.RecupereParNumeroDeSerie(string numero)
       {
          return this.RecupereParNumeroDeSerie(numero);
       }
    }
    Ici, on voit que j'ai maintenant deux méthodes RecupereParNumeroDeSerie. Première chose que l'on constate, c'est qu'elles ont la même signature (même nom, même paramètres), mais diffèrent par leur type de retour. Normalement, ce genre de pratique est interdite et génère une erreur de compilation. Néanmoins, ici, une des méthodes est une implémentation explicite d'une interface, ce qui change complètement la donne, car pour pouvoir l'appeler, il faut impérativement manipuler une variable ayant comme type l'interface IUsine (et donc il n'y a pas d'ambiguïté et les deux définitions sont donc possibles).

    Ainsi, ici, si je manipule une instance de MonUsineAAvion et que je récupère un moyen de locomotion par son numéro de série, j'obtiens directement une instance de IAvion ! A contrario, si je suis plus générique et que je manipule une instance de IUsine (je ne sais pas a priori quel type d'usine je manipule), alors la même méthode me renverra une instance de IMoyenLocomotion.

    On a donc réussi à spécialiser type retourné pour ne pas avoir à caster l'objet (on peut renvoyer complètement autre chose et/ou changer drastiquement le comportement de la méthode en fonction du type d'appel, mais je le déconseille fortement pour des raisons de clarté évidente !).

    Conclusion
    Voilà, j'ai tout dis ! Hormis quelques cas particulier, j'évite l'usage d'interface explicite. Donc, implémenter d'office, non. C'est inutile, lourd, et potentiellement dangereux.

    A noter aussi l'abus de langage sur l'implémentation explicite/implicite d'une interface. En réalité, c'est l'implémentation implicite/explicité d'un membre d'une interface, c'est-à-dire qu'une partie d'une interface peut très bien être implémentée de manière implicite et une autre de manière explicite !
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  4. #4
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2014
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2014
    Messages : 52
    Points : 158
    Points
    158
    Par défaut
    Merci pour ces précisions et effectivement il s'agit de l'implémentation d'un membre.

    Une explication limpide!

    Bonne journée.

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

Discussions similaires

  1. [Debutant] implémenter un URL
    Par nadhem dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 13/09/2007, 11h43
  2. Réponses: 12
    Dernier message: 12/07/2007, 14h17
  3. debut en interfaces graphiques
    Par dimainfo dans le forum Interfaces Graphiques en Java
    Réponses: 5
    Dernier message: 21/06/2007, 14h56
  4. Implémenter interface ICloneable
    Par babozfr dans le forum C++/CLI
    Réponses: 5
    Dernier message: 16/01/2007, 20h24
  5. [Débutant] Explication implémentation interface
    Par HaTnuX dans le forum Langage
    Réponses: 3
    Dernier message: 16/01/2007, 16h37

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