Pourquoi les interfaces sont-elles utiles?

158

J'étudie et je code en C # depuis quelque temps maintenant. Mais encore, je ne peux pas comprendre l'utilité des interfaces. Ils apportent trop peu à la table. À part fournir les signatures de fonction, ils ne font rien. Si je me souviens des noms et de la signature des fonctions à implémenter, ils ne sont pas nécessaires. Ils ne sont là que pour s’assurer que lesdites fonctions (dans l’interface) sont implémentées dans la classe qui en hérite.

C # est un excellent langage, mais il vous donne parfois l’impression que Microsoft crée d’abord le problème (ne permet pas l’héritage multiple), puis fournit la solution, ce qui est plutôt fastidieux.

C'est ce que je comprends, basé sur une expérience de codage limité. Quelle est votre vision des interfaces? À quelle fréquence les utilisez-vous et qu'est-ce qui vous fait le faire?

Pankaj Upadhyay
la source
55
"Si je me souviens des noms et de la signature des fonctions à implémenter, ils ne sont pas nécessaires." Cette déclaration me fait penser que vous devriez examiner un peu plus les avantages des langages statiques .
Steven Jeuris
37
Oubliez C #, oubliez Java, oubliez le langage. C'est simplement penser en termes de OO. Je vous encourage à consulter des ouvrages de lectures telles que Robert C. Martin, Martin Fowler, Michael Feathers, le Gang of Four, etc., car cela vous aidera à approfondir votre réflexion.
Anthony Pegram le
27
Il m'a fallu plus de deux ans pour vraiment comprendre à quoi servent les interfaces. Ma suggestion: étudier les modèles de conception. Comme la plupart d’entre eux reposent sur des interfaces, vous comprendrez vite pourquoi elles sont si utiles.
Oliver Weiler
37
Vous avez beaucoup à apprendre à un ami.
ChaosPandion le
60
@ ChaosPandion nous avons tous beaucoup à apprendre
Kenwarner

Réponses:

151

Ils ne sont là que pour s’assurer que lesdites fonctions (dans l’interface) sont implémentées dans la classe qui en hérite.

Correct. C'est un avantage suffisamment impressionnant pour justifier la fonctionnalité. Comme d'autres l'ont dit, une interface est une obligation contractuelle d'implémenter certaines méthodes, propriétés et événements. L'avantage incontestable d'un langage à typage statique est que le compilateur peut vérifier qu'un contrat sur lequel votre code s'appuie est réellement respecté.

Cela dit, les interfaces sont un moyen assez faible de représenter les obligations contractuelles. Si vous souhaitez une manière plus forte et plus flexible de représenter les obligations contractuelles, reportez-vous à la fonctionnalité Contrats de code fournie avec la dernière version de Visual Studio.

C # est un excellent langage, mais il vous donne parfois l’impression que Microsoft crée d’abord le problème (ne permet pas l’héritage multiple), puis fournit la solution, ce qui est plutôt fastidieux.

Et bien je suis content que ça te plaise.

Toutes les conceptions logicielles complexes résultent de la mise en balance de caractéristiques contradictoires et de la recherche du «point idéal» offrant des avantages considérables pour des coûts minimes. Nous avons appris de douloureuses expériences que les langages autorisant l'héritage multiple aux fins du partage de la mise en œuvre ont des avantages relativement modestes et des coûts relativement élevés. Autoriser l'héritage multiple uniquement sur les interfaces, qui ne partagent pas les détails de la mise en œuvre, offre de nombreux avantages de l'héritage multiple sans la plupart des coûts.

Eric Lippert
la source
Je lisais simplement "Microsoft crée le problème en n'autorisant pas l'héritage multiple" et j'ai pensé qu'Eric Lippert aurait quelque chose à dire à ce sujet.
configurateur
Plus pertinent pour cette réponse: Eric, vous référez le demandeur aux codes de contrats, mais ils sont terriblement incomplets; toute autre chose que les contrats les plus élémentaires n'est pas exécutable par le vérificateur statique. J'ai essayé d'utiliser Code Contract sur un petit projet; J'ai ajouté des centaines de lignes pour chaque méthode spécifiant tout ce que je pouvais sur les entrées et les sorties, et pourtant, j'ai dû ajouter beaucoup d' Assumeappels, pour des cas comme des membres de tableau ou d'énumération. Après avoir tout ajouté et vu le gâchis statiquement vérifié que j'avais, je suis revenu en contrôle de source car cela réduisait la qualité de mon projet.
configurateur
17
@configurator: ils sont incomplets car ils ne peuvent pas être complets; La vérification de programme statique avec des contrats arbitraires équivaut à résoudre le problème Halting. (Par exemple, vous pourriez écrire un contrat de code indiquant que les arguments d'une méthode doivent être un contre-exemple du dernier théorème de Fermat; mais le vérificateur statique ne pourra pas vérifier qu'il n'existe aucun argument de ce type.) Je dois l’utiliser judicieusement si vous vous attendez à ce que le vérificateur statique termine son travail avant la mort de l’univers. (Si votre plainte est que la BCL est insuffisamment annotée: je suis d'accord.)
Eric Lippert le
2
Je m'attends à ce qu'il se rende compte que lorsqu'une méthode promet que le tableau de résultats ou l'énumération ne contient pas null, la méthode using peut utiliser les valeurs dans des emplacements qui n'autorisent pas les valeurs NULL. C'est la seule chose à laquelle je m'attendais de ce qu'il ne le fasse pas, et il était trop important pour être utilisable sans lui; toute autre chose n'est qu'un bonus. Cela dit, je sais que la vérification statique ne peut être complète, raison pour laquelle j'estime que ce n'est pas une bonne alternative sur laquelle s'appuyer pour des contrats.
configurateur
9
+1 pour "Eh bien, je suis heureux que cela vous plaise." Et tous les autres trucs aussi.
Robert S.
235

entrez la description de l'image ici

Donc, dans cet exemple, le PowerSocket ne sait rien d’autre sur les autres objets. Les objets dépendent tous de la puissance fournie par le PowerSocket. Ils implémentent donc IPowerPlug et peuvent ainsi s'y connecter.

Les interfaces sont utiles car elles fournissent des contrats que les objets peuvent utiliser pour travailler ensemble sans avoir besoin de rien savoir les uns des autres.

Slomojo
la source
4
L'objet en bas à gauche ne semble pas implémenter IPowerPlug =)
Steven Striga
100
Bon sang, mais nous devrons utiliser un modèle d'adaptateur pour pouvoir utiliser l'IPowerPlug dans différents pays!
Steven Jeuris
Il n'est pas sûr de manipuler un périphérique pour contourner l'interface (mais certaines personnes le font encore, citant souvent les performances comme une excuse non vérifiée) et susceptibles de provoquer des incendies.
YoungJohn
4
Cette réponse est tout simplement incroyable ...
Mario Garcia
Souligner simplement cette réponse ne dit pas - dans cet exemple particulier - pourquoi utiliser une interface serait préférable à l'héritage. Quelqu'un de nouveau dans les interfaces peut demander pourquoi ils n’héritent pas tous simplement, par exemple MainsPoweredDevice qui fournit toutes les fonctionnalités de prise, le socket acceptant tout ce qui est dérivé de MainsPoweredDevice.
ingrédient_15939
145

À part fournir les signatures de fonction, ils ne font rien. Si je me souviens des noms et de la signature des fonctions à implémenter, ils ne sont pas nécessaires

Le but des interfaces n'est pas de vous aider à vous rappeler quelle méthode à implémenter, c'est ici pour définir un contrat . Dans l' exemple de foreach P.Brian.Mackey (ce qui s'avère être faux , mais on s'en fiche), IEnumerable définit un contrat entre foreach et toute autre chose énumérable. Il dit: "Qui que vous soyez, tant que vous respectez le contrat (implémentez IEnumerable), je vous promets que je vais parcourir tous vos éléments". Et c'est excellent (pour un langage non dynamique).

Grâce aux interfaces, vous pouvez obtenir un couplage très faible entre deux classes.

David
la source
Je n'aime pas utiliser le terme "dactylographie" parce qu'il signifie différentes choses pour différentes personnes. Nous utilisons une correspondance de modèle pour la boucle "foreach" car lors de sa conception, IEnumerable <T> n'était pas disponible. Nous utilisons un filtrage par motif pour LINQ car le système de type C # est trop faible pour capturer le "motif monade" dont nous avons besoin; vous auriez besoin de quelque chose comme le système de type Haskell.
Eric Lippert
@Eric: "Pattern matching" n'a-t-il pas le même problème? Quand je l'entends, je pense à F # / Scala / Haskell. Mais j'imagine que c'est une idée plus large que la frappe au canard.
Daniel
@ Daniel: Oui, je suppose que oui. Je suppose qu'il en a six d'une heure et demie de l'autre!
Eric Lippert
36

Les interfaces sont le meilleur moyen de conserver des constructions bien découplées.

Lorsque vous écrivez des tests, vous constaterez que des classes concrètes ne fonctionneront pas dans votre environnement de test.

Exemple: vous souhaitez tester une classe qui dépend d'une classe de service d'accès aux données . Si cette classe parle à un service Web ou à une base de données, votre test unitaire ne s'exécutera pas dans votre environnement de test (il est également devenu un test d'intégration).

Solution? Utilisez une interface pour votre service d'accès aux données et simulez cette interface afin de pouvoir tester votre classe en tant qu'unité.

D'autre part, WPF & Silverlight ne jouent pas du tout avec les interfaces en matière de reliure. C'est une jolie vilaine ride.

Sheldon Warkentin
la source
2
entendre entendre! Les interfaces ont été inventées pour résoudre d'autres problèmes, tels que le polymorphisme. Cependant, pour moi, ils entrent en jeu lorsqu'ils mettent en œuvre un modèle d'injection de dépendance.
Andy
29

Les interfaces sont l'épine dorsale du polymorphisme (statique)! L'interface est ce qui compte. L'héritage ne fonctionnerait pas sans interfaces, car les sous-classes héritent essentiellement de l'interface déjà implémentée du parent.

Combien de fois en utilisez-vous et qu'est-ce qui vous fait le faire ??

Assez souvent. Tout ce qui doit être connectable est une interface dans mes applications. Souvent, vous avez des classes par ailleurs non liées qui doivent fournir le même comportement. Vous ne pouvez pas résoudre de tels problèmes avec l'héritage.

Besoin de différents algorithmes pour effectuer des opérations sur les mêmes données? Utilisez une interface ( voir modèle de stratégie )!

Voulez-vous utiliser différentes implémentations de liste? Code contre une interface et l'appelant n'a pas besoin de s'inquiéter de la mise en œuvre!

Il a été considéré comme une bonne pratique (pas seulement en POO) de coder des interfaces depuis des siècles, pour une raison unique: il est facile de modifier une implémentation lorsque vous réalisez qu'elle ne correspond pas à vos besoins. C’est assez fastidieux d’essayer d’atteindre cet objectif uniquement avec un héritage multiple ou de créer des classes vides afin de fournir l’interface nécessaire.

Falcon
la source
1
Jamais entendu parler de polymorphie, tu veux dire polymorphisme?
Steven Jeuris
1
Cela étant dit, si Microsoft avait initialement autorisé l'héritage multiple, il n'y aurait aucune raison de l'existence d'interfaces
Pankaj Upadhyay,
10
@Pankaj Upadhyay: l'héritage multiple et les interfaces sont deux paires de chaussures différentes. Que faire si vous avez besoin d'une interface de deux classes non liées avec un comportement différent? Vous ne pouvez pas résoudre ce problème par héritage multiple. De toute façon, vous devez l’appliquer séparément. Et ensuite, vous aurez besoin de quelque chose pour décrire l'interface afin de fournir un comportement polymorphe. L'héritage multiple est une impasse dans de nombreux cas, et il est trop facile de se tirer une balle dans le pied tôt ou tard.
Falcon
1
Permet de simplifier. Si mon interface implémente deux fonctions Display et Comment, je dispose d'une classe qui les implémente. Alors pourquoi pas je supprime l'interface et utilise les fonctions directement. Ce que je dis, c'est qu'ils vous fournissent simplement le nom des fonctions qui doivent être implémentées. Si on peut se souvenir de ces fonctions, alors pourquoi créer une interface
Pankaj Upadhyay
9
@Pankaj, si c'est tout ce dont vous avez besoin de l'interface, ne l'utilisez pas. Vous utilisez une interface lorsque vous avez un programme qui veut ignorer tous les aspects de la classe et y accéder par son type de base, à savoir l'interface. Ils n'ont besoin de connaître aucune des sous-classes, mais simplement du type d'interface. En tant que tel, vous pouvez ensuite appeler la méthode implémentée de la sous-classe via la référence à l'interface de l'objet. C'est un héritage de base et des éléments de conception. Sans lui, vous pourriez aussi bien utiliser C. Même si vous ne l'utilisez pas explicitement, le framework ne fonctionnerait pas sans cela.
Jonathan Henson
12

Vous avez probablement utilisé foreachet trouvé cet outil d'itération très utile. Saviez-vous qu'il faut une interface pour fonctionner, IEnumerable ?

C'est certainement un cas concret qui parle de l'utilité d'une interface.

P.Brian.Mackey
la source
5
En fait, foreach ne nécessite pas IEnumerable: msdn.microsoft.com/en-us/library/9yb8xew9%28VS.80%29.aspx
Matt H
1
J'ai étudié tout ça, mais c'est comme tenir l'oreille avec l'autre main. Si l'héritage multiple était autorisé, l'interface aurait été un choix éloigné.
Pankaj Upadhyay
2
Les interfaces sont un héritage multiple, quelque chose qui est souvent oublié. Cependant, ils ne permettent pas l'héritage multiple de comportement et d'état. Les mixins ou les traits permettent un héritage multiple de comportement, mais pas un état partagé qui pose problème: en.wikipedia.org/wiki/Mixin
Matt H
@Pankaj, offtopic, mais cela vous dérange-t-il si je vous demande quelle est votre langue maternelle? "Tenir l'oreille de l'autre main" est un très bon langage et j'étais curieux de savoir d'où ça vient.
Kevin
3
@ Iceman. LOL .... Je suis d'Inde. Et ici, c’est un idiome commun qui signifie que faire des choses faciles est difficile.
Pankaj Upadhyay
11

Les interfaces servent à coder les objets, tout comme une fiche au câblage domestique. Souhaitez-vous souder votre radio directement au câblage de votre maison? Que diriez-vous de votre aspirateur? Bien sûr que non. La fiche et la prise de courant dans laquelle elle s’insère constituent l’interface entre le câblage de votre domicile et le périphérique qui en a besoin. Le câblage de votre domicile n'a pas besoin de connaître le périphérique, à part qu'il utilise une fiche à trois broches mise à la terre et qu'il nécessite une alimentation électrique à 120VAC <= 15A. Inversement, le périphérique ne nécessite aucune connaissance compliquée de la connexion de votre maison. Il comporte en outre une ou plusieurs prises à trois broches idéalement placées qui fournissent 120 VCA <= 15A.

Les interfaces remplissent une fonction très similaire dans le code. Un objet peut déclarer qu'une variable, un paramètre ou un type de retour particulier est d'un type d'interface. L'interface ne peut pas être instanciée directement avec un newmot clé, mais mon objet peut être donné, ou trouver, la mise en oeuvre de cette interface avec laquelle il devra travailler. Une fois que l'objet a sa dépendance, il n'a pas besoin de savoir exactement quelle est cette dépendance, il doit juste savoir qu'il peut appeler les méthodes X, Y et Z sur la dépendance. Les implémentations de l'interface n'ont pas besoin de savoir comment elles seront utilisées, elles doivent juste savoir qu'elles devront fournir les méthodes X, Y et Z avec des signatures particulières.

Ainsi, en résumant plusieurs objets derrière la même interface, vous fournissez un ensemble commun de fonctionnalités à tout consommateur d’objets de cette interface. Vous n'êtes pas obligé de savoir que l'objet est, par exemple, une liste, un dictionnaire, une liste LinkedList, une liste OrderedList ou autre. Comme vous savez que tous ces éléments sont IEnumerables, vous pouvez utiliser les méthodes de IEnumerable pour parcourir chaque élément de ces collections, un à la fois. Vous n'avez pas besoin de savoir qu'une classe de sortie est un ConsoleWriter, un FileWriter, un NetworkStreamWriter ou même un MulticastWriter prenant d'autres types d'écrivains; tout ce que vous devez savoir, c'est qu'ils sont tous des IWriters (ou autre), et ils ont donc une méthode "Write" dans laquelle vous pouvez passer une chaîne, et cette chaîne sera sortie.

KeithS
la source
7

Bien qu'il soit clair que le programmeur (au moins tout d'abord) a un héritage multiple, il s'agit d'une omission presque triviale et vous ne devriez (dans la plupart des cas) pas compter sur l'héritage multiple. Les raisons de ceci sont complexes, mais si vous voulez vraiment en apprendre plus, considérez l'expérience des deux langages de programmation les plus célèbres (par TIOBE index ) qui le supportent: C ++ et Python (respectivement 3ème et 8ème).

En Python, l'héritage multiple est pris en charge, mais il est presque universellement mal compris par les programmeurs. Pour vous dire que vous savez comment ça marche, entend lire et comprendre ce document sur le sujet: Ordre de résolution de méthode . Une autre chose qui se passe en Python, c'est que les interfaces sont en quelque sorte entrées dans le langage - Zope.Interfaces.

Pour C ++, recherchez "la hiérarchie du diamant C ++" dans Google et voyez la laideur qui est sur le point de vous couvrir. Les professionnels de C ++ savent utiliser l'héritage multiple. Tous les autres jouent généralement sans savoir quels seront les résultats. Une autre chose qui montre à quel point les interfaces sont utiles est le fait que, dans de nombreux cas, une classe peut avoir besoin de redéfinir complètement le comportement de son parent. Dans de tels cas, l'implémentation parent est inutile et n'impose à la classe enfant que de la mémoire pour les variables privées du parent, ce qui n'a peut-être pas d'importance dans l'âge C #, mais qui importe lorsque vous effectuez une programmation intégrée. Si vous utilisez une interface, ce problème est inexistant.

En conclusion, les interfaces sont, à mon avis, un élément essentiel de la programmation orientée objet, car elles font respecter un contrat. L'héritage multiple est utile dans des cas limités, et en général uniquement pour les gars qui savent l'utiliser. Donc, si vous êtes débutant, vous êtes celui qui est traité par le manque d'héritage multiple - cela vous donne une meilleure chance de ne pas vous tromper .

De plus, historiquement, l'idée d'une interface est ancrée bien avant les spécifications de conception C # de Microsoft. La plupart des gens considèrent que C # est une mise à niveau par rapport à Java (au sens le plus large du terme) et devinent d'où vient que C # tire ses interfaces - Java. Protocole est un ancien mot pour le même concept, et il est bien plus ancien que .NET.

Mise à jour: Je vois maintenant que j'aurais peut-être répondu à une question différente - Pourquoi les interfaces plutôt que l'héritage multiple, mais cela semblait être la réponse que vous cherchiez. En outre, une langue OO devrait avoir au moins une des deux et les autres réponses ont couvert votre question initiale.

George Penn.
la source
6

Il m'est difficile d'imaginer un code C # propre et orienté objet sans utiliser d'interfaces. Vous les utilisez chaque fois que vous souhaitez imposer la disponibilité de certaines fonctionnalités sans forcer les classes à hériter d'une classe de base spécifique, ce qui permet à votre code d'avoir le niveau de couplage (faible) approprié.

Je ne suis pas d'accord pour dire que l'héritage multiple est mieux que d'avoir des interfaces, même avant de commencer à argumenter que l'héritage multiple vient avec son propre ensemble de problèmes. Les interfaces sont un outil de base pour permettre le polymorphisme et la réutilisation du code, de quoi a-t-il besoin de plus?

Daniel B
la source
5

Personnellement, j'adore la classe abstraite et l'utilise plus qu'une interface. La principale différence vient de l'intégration avec des interfaces .NET telles que IDisposable, IEnumerable, etc., et COM interop. De plus, l'interface demande un peu moins d'effort en écriture qu'une classe abstraite et une classe peut implémenter plusieurs interfaces alors qu'elle ne peut hériter que d'une classe.

Cela dit, je trouve que la plupart des choses pour lesquelles je voudrais utiliser une interface sont mieux servies par une classe abstraite. Les fonctions virtuelles pures - fonctions abstraites - vous permettent de forcer un implémenteur à définir une fonction similaire à la manière dont une interface force un implémenteur à définir tous ses membres.

Toutefois, vous utilisez généralement une interface lorsque vous ne souhaitez pas imposer une conception donnée à la super-classe, alors que vous utiliseriez une classe abstraite pour obtenir une conception réutilisable déjà largement implémentée.

J'ai beaucoup utilisé les interfaces avec l'écriture d'environnements de plug-in utilisant l'espace de noms System.ComponentModel. Ils sont très utiles.

Jonathan Henson
la source
1
Très bien mis! Je suppose que vous aimerez mon article sur les classes abstraites. L'abstraction est tout .
Steven Jeuris
5

Je peux dire que je rapporte à cela. Quand j'ai commencé à apprendre sur OO et C #, moi aussi, je n'ai pas eu d'interfaces. C'est bon. Nous devons juste trouver quelque chose qui vous fera apprécier le confort des interfaces.

Laissez-moi essayer deux approches. Et pardonnez-moi pour les généralisations.

Essayer 1

Dites que vous êtes un anglophone. Vous allez dans un autre pays où l'anglais n'est pas la langue maternelle. Vous avez besoin d'aide. Vous avez besoin de quelqu'un qui peut vous aider.

Demandez-vous: "Hey, êtes-vous né aux États-Unis?" C'est l'héritage.

Ou demandez-vous: "Hey, parlez-vous anglais"? Ceci est l'interface.

Si vous vous souciez de ce qu'il fait, vous pouvez compter sur des interfaces. Si vous vous souciez de ce qui est, vous comptez sur l'héritage.

C'est correct de compter sur l'héritage. Si vous avez besoin de quelqu'un qui parle anglais, qui aime le thé et le football, vous feriez mieux de demander un Britannique. :)

Essayez 2

Ok, essayons un autre exemple.

Vous utilisez différentes bases de données et vous devez implémenter des classes abstraites pour les utiliser. Vous passerez votre classe à une classe du fournisseur de base de données.

public abstract class SuperDatabaseHelper
{
   void Connect (string User, string Password)
}

public abstract class HiperDatabaseHelper
{
   void Connect (string Password, string User)
}

L'héritage multiple, vous dites? Essayez cela avec le cas ci-dessus. Tu ne peux pas. Le compilateur ne saura pas quelle méthode Connect vous essayez d'appeler.

interface ISuperDatabaseHelper
{
  void Connect (string User, string Password)
}

interface IHiperDatabaseHelper
{
   void Connect (string Password, string User)
}

Nous pouvons maintenant travailler, du moins en C #, avec lequel nous pouvons implémenter des interfaces de manière explicite.

public class MyDatabaseHelper : ISuperDatabaseHelper, IHiperDatabaseHelper
{
   IHiperDataBaseHelper.Connect(string Password, string User)
   {
      //
   }

   ISuperDataBaseHelper.Connect(string User, string Password)
   {
      //
   }

}

Conclusion

Les exemples ne sont pas les meilleurs, mais je pense que ça donne raison.

Vous n'obtiendrez que des interfaces lorsque vous en ressentez le besoin. Jusqu'à ce que vous pensiez qu'ils ne sont pas pour vous.

Luiz Angelo
la source
Le premier essai est ce qui a donné mon vote.
dimanche
1
J'utilise totalement l'analogie américaine / anglophone à partir de maintenant. C'est fantastique.
Bryan Boettcher
Expliqué d'une manière plus simple! Fantastique.
Aimal Khan
4

Il y a 2 raisons principales:

  1. Absence d'héritage multiple. Vous pouvez hériter d'une classe de base et implémenter un nombre illimité d'interfaces. C'est la seule façon de "faire" plusieurs héritages dans .NET.
  2. Interopérabilité COM. Tout ce qui devra être utilisé par les technologies "plus anciennes" devra avoir des interfaces définies.
Tangurena
la source
Le point 1 est certainement la raison et la raison développée par les développeurs de Microsoft eux
Pankaj Upadhyay
1
@Pankja En fait, ils ont pris l'idée d'interface de Java (comme une bonne partie des fonctionnalités de C #).
Oliver Weiler
3

L'utilisation d'interfaces aide un système à rester découplé et donc plus facile à refactoriser, à modifier et à redéployer. C’est un concept fondamental pour l’orthodoxie orientée objet et j’en ai été informé lorsque des gourous du C ++ ont créé des "classes abstraites pures" qui sont tout à fait équivalentes aux interfaces.

Jesse C. Slicer
la source
Le découplage est important car il permet de garder différentes composantes d'un système indépendantes les unes des autres. Même des modifications importantes dans un composant ne se répercutent pas sur les autres composants. Considérez les fiches d’alimentation comme une interface avec votre entreprise de services publics (spécifiant la tension, les broches physiques et le format de la fiche). Grâce à cette interface, l'utilitaire peut complètement changer sa façon de produire de l'énergie (par exemple, utiliser la technologie solaire), mais aucun des appareils ne remarquera même un changement.
miraculixx
3

Les interfaces en elles-mêmes ne sont pas très utiles. Mais une fois implémenté par des classes concrètes, vous voyez que cela vous donne la possibilité d’avoir une ou plusieurs implémentations. L'avantage est que les objets utilisant l'interface n'ont pas besoin de savoir comment vont les détails de l'implémentation réelle - cela s'appelle l'encapsulation.

Ronald
la source
2

Ils sont principalement utilisés pour la réutilisation du code. Si vous codez sur l'interface, vous pouvez utiliser une classe différente qui hérite de cette interface et ne pas tout casser.

En outre, ils sont très utiles dans les services Web où vous voulez que le client sache ce qu’une classe fait (pour qu’elle puisse la consommer), mais ne leur donnez pas le code réel.

Tom Squires
la source
2

En tant que jeune programmeur / développeur, rien qu'en apprenant le C #, vous ne verrez peut-être pas l'utilité d'une interface, car vous pourriez écrire vos codes à l'aide de vos classes et le code fonctionne bien, mais dans le scénario réel, la création d'une application évolutive, robuste et maintenable implique l'utilisation de certaines architectures et modèles, qui ne peuvent être rendus possibles qu’en utilisant l’interface, par exemple en injection de dépendance.

Ayobami Adewole
la source
1

Une implémentation du monde réel:

Vous pouvez convertir un objet en tant que type d'interface:

IHelper h = (IHelper)o;
h.HelperMethod();

Vous pouvez créer une liste d'une interface

List<IHelper> HelperList = new List<IHelper>();

Avec ces objets, vous pouvez accéder à n’importe quelle méthode ou propriété d’interface. De cette manière, vous pouvez définir une interface pour votre partie d'un programme. Et construisez la logique autour de cela. Ensuite, quelqu'un d'autre peut implémenter votre interface dans leurs objets Business. Si les BO changent, ils peuvent changer la logique des composants d'interface sans exiger de modification de la logique de votre pièce.

SoylentGray
la source
0

Les interfaces permettent une modularité de type plugin en fournissant un mécanisme permettant aux classes de comprendre (et de s’abonner à) certains types de messages fournis par votre système. Je vais élaborer.

Dans votre application, vous décidez que chaque fois qu'un formulaire est chargé ou rechargé, vous souhaitez que tous les éléments qu'il héberge soient effacés. Vous définissez une IClearinterface qui implémente Clear. En outre, vous décidez que chaque fois que l'utilisateur appuie sur le bouton d'enregistrement, le formulaire doit tenter de conserver son état. Ainsi, tout ce qui reste ISavereçoit un message pour persister son état. Bien entendu, sur le plan pratique, la plupart des interfaces traitent plusieurs messages.

Ce qui distingue les interfaces, c'est qu'un comportement commun peut être obtenu sans héritage. La classe qui implémente une interface donnée comprend simplement comment se comporter lorsqu'une commande est émise (un message de commande) ou comment répondre à une requête (un message d'interrogation). Essentiellement, les classes de votre application comprennent les messages fournis par votre application. Cela facilite la construction d'un système modulaire dans lequel les choses peuvent être branchées.

Dans la plupart des langages, il existe des mécanismes (tels que LINQ ) pour interroger des éléments liés à une interface. Cela vous aidera généralement à éliminer la logique conditionnelle, car vous n'aurez pas à dire à des choses différentes (qui ne sont pas nécessairement dérivées de la même chaîne d'héritage) comment se comporter de manière similaire (selon un message particulier). Au lieu de cela, vous rassemblez tout ce qui comprend un certain message (respecte une interface) et publiez le message.

Par exemple, vous pourriez remplacer ...

Me.PublishDate.Clear()
Me.Subject.Clear()
Me.Body.Clear()

...avec:

For Each ctl As IClear In Me.Controls.OfType(Of IClear)()
    ctl.Clear()
Next

Ce qui ressemble effectivement beaucoup à:

Écoutez, écoutez! Tous ceux qui comprennent le nettoyage vont-ils Clearmaintenant!

De cette façon, nous pouvons éviter par programmation de demander à chaque chose de se vider d'elle-même. Et lorsque des éléments dissociables sont ajoutés à l'avenir, ils répondent simplement sans code supplémentaire.

Mario T. Lanza
la source
0

Le pseudocode est le suivant:

class MyClass{

    private MyInterface = new MyInterfaceImplementationB();

    // Code using Thingy 

}

interface MyInterface{

    myMethod();

}

class MyInterfaceImplementationA{ myMethod(){ // method implementation A } }

class MyInterfaceImplementationB{ myMethod(){ // method implementation B } }

class MyInterfaceImplementationC{ myMethod(){ // method implementation C } }

Les dernières classes peuvent être des implémentations complètement différentes.

À moins que l'héritage multiple ne soit possible, l'héritage impose l'implémentation de la classe parente rendant les choses plus rigides. En revanche, la programmation par rapport aux interfaces peut permettre à votre code ou à un framework d’être extrêmement flexible. Si vous rencontrez un jour un cas où vous souhaitiez pouvoir échanger des classes dans une chaîne d'héritage, vous comprendrez pourquoi.

Par exemple, un framework qui fournit à l’origine un lecteur destiné à lire des données à partir d’un disque pourrait être ré-implémenté pour faire quelque chose de la même nature mais d’une manière totalement différente. Comme interpréter le code Morse par exemple.

James Poulson
la source