Quelle est la différence entre une interface et une classe, et pourquoi devrais-je utiliser une interface lorsque je peux implémenter les méthodes directement dans la classe?


118

Je suis conscient que c'est une question très basique, mais un intervieweur m'a posé une question très astucieuse et j'étais impuissant :(

Je ne connais que la définition matérielle ou théorique d'une interface et je l'ai également implémentée dans de nombreux projets sur lesquels j'ai travaillé. Mais je ne comprends vraiment pas pourquoi et comment est-ce utile.

Je ne comprends pas non plus une chose dans l'interface. c'est à dire par exemple, nous utilisons

conn.Dispose();dans enfin bloc. Mais je ne vois pas que cette classe implémente ou hérite de la classe IDisposableinterface ( SqlConnection) que je veux dire. Je me demande comment je peux simplement appeler le nom de la méthode. Dans le même ordre d'idées, je ne comprends pas comment la méthode Dispose fonctionne car nous devons implémenter le corps de la fonction avec notre propre implémentation pour toutes les méthodes d'interface. Alors, comment les interfaces sont-elles acceptées ou nommées comme contrats? Ces questions ont continué à rouler dans mon esprit jusqu'à présent et, franchement, je n'ai jamais vu de fil conducteur qui expliquerait mes questions d'une manière que je puisse comprendre.

MSDN, comme d'habitude, semble très effrayant et aucune ligne n'est claire là-bas ( Mes amis, veuillez excuser qui sont dans le développement de haut niveau, je pense fermement que tout code ou article devrait atteindre l'esprit de quiconque le voit, donc comme beaucoup d'autres le disent, MSDN n'est pas utile ).

L'intervieweur a déclaré:

Il a 5 méthodes et il est heureux de l'implémenter directement dans la classe, mais si vous devez opter pour une classe ou une interface abstraite, laquelle choisissez-vous et pourquoi? Je lui ai répondu à tous les trucs que j'ai lus dans divers blogs en disant l'avantage et le désavantage de la classe abstraite et de l'interface, mais il n'est pas convaincu, il essaie de comprendre "Pourquoi l'interface" en général. "Pourquoi une classe abstraite" en général même si je ne peux implémenter les mêmes méthodes qu'une seule fois et ne pas la changer.

Je ne vois nulle part sur le net, je pourrais obtenir un article qui m'expliquerait clairement sur les interfaces et son fonctionnement. Je fais partie de ces nombreux programmeurs, qui ne connaissent toujours pas les interfaces (je connais la théorie et les méthodes que j'ai utilisées) mais qui ne sont pas convaincus de l'avoir bien compris.


4
Les interfaces sont celles que j'ai eu du mal à comprendre également. Bonne question.
Brian

4
la programmation à un contrat abstrait plutôt qu'à une implémentation concrète .... En bref, cela signifie que vous pouvez remplacer n'importe quel objet qui implémente une interface lorsqu'une interface est requise.
Mitch Wheat

7
SqlConnectionhérite de System.ComponentModel.Componentqui implémente IDisposable.
Lee

2
@MitchWheat - Ce n'est pas censé être un exemple, la question demande comment SqlConnectionimplémente IDisposable.
Lee

Oh Lee, cela m'a fait comprendre merci. Mais je ne vois toujours pas comment ni où la fonctionnalité de la méthode «Dispose» est définie.
Apprenti

Réponses:


92

Les interfaces sont excellentes lorsque vous souhaitez créer quelque chose comme ça:

using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a specific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as a parameter any object that implements IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

Dans mon exemple, je pourrais être un développeur qui écrit MyLogClass, et les autres développeurs, pourraient créer leurs classes, et quand ils voulaient se connecter, ils implémentaient l'interface IMyLogInterface. C'est comme ils me demandaient ce qu'ils devaient implémenter pour utiliser la WriteLog()méthode MyLogClass. La réponse qu'ils trouveront dans l'interface.


3
Hé, ça ressemble à un très bon ingrédient à comprendre, je l'apprécie vraiment, merci beaucoup :) :)
Apprenti

14
Ma question est de savoir si vous instanciez MyClasset MyOtherClasspourquoi n'appeleriez-vous pas simplement aClass.WriteLog()pourquoi ajouter cette étape supplémentaire. L'implémentation de WriteLog()resterait différente pour chacune des classes mais vous avez déjà l'objet alors pourquoi le passer à une classe de gestionnaire?
Zach M.

Hm peut-être que si vous mettez votre exemple de journalisation sur nugget, il serait plus simple pour les autres d'utiliser votre enregistreur, sans connaître les détails ... mais d'un autre côté, ce n'est toujours pas une classe universelle, (ea je pourrais écrire un interface avec journalisation ET niveaux allert) sont toujours uniquement dans votre champ d'application. donc à part vous pour qui en profite?.
user3800527

2
@ZachM. Si j'ai raison, la réponse signifie qu'il n'instanciera pas les classes, mais d'autres développeurs instancieront les classes et les passeront en paramètre à la MyLogClass WriteLogméthode. Ainsi sa méthode peut gérer n'importe quel objet implémentant IMyLogInterface. Voici un autre article intéressant.
shaijut

1
Ma question est pourquoi Interface ??? Le scénario ci-dessus peut également être réalisé par une classe abstraite avec toutes les méthodes abstraites.
Abhijit Ojha

52

Une des raisons pour lesquelles j'utilise des interfaces est que cela augmente la flexibilité du code. Disons que nous avons une méthode qui prend un objet de type de classe Account comme paramètre, tel que:

public void DoSomething(Account account) {
  // Do awesome stuff here.
}

Le problème avec cela, c'est que le paramètre de méthode est fixé vers une implémentation d'un compte. C'est bien si vous n'avez jamais besoin d'un autre type de compte. Prenons cet exemple, qui utilise à la place une interface de compte comme paramètre.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

Cette solution n'est pas figée vers une implémentation, ce qui signifie que je peux lui passer un SuperSavingsAccount ou un ExclusiveAccount (tous deux implémentant l'interface IAccount) et obtenir un comportement différent pour chaque compte implémenté.


45

Les interfaces sont des contrats que les exécutants doivent suivre. Les classes abstraites permettent des contrats plus des implémentations partagées - ce que les interfaces ne peuvent pas avoir. Les classes peuvent implémenter et hériter de plusieurs interfaces. Les classes ne peuvent étendre qu'une seule classe abstraite.

Pourquoi Interface

  • Vous n'avez pas d'implémentation de code par défaut ou partagé
  • Vous souhaitez partager des contrats de données (services web, SOA)
  • Vous avez différentes implémentations pour chaque implémenteur d'interface ( IDbCommanda SqlCommandet OracleCommandqui implémentent l'interface de manière spécifique )
  • Vous souhaitez prendre en charge l'héritage multiple .

Pourquoi abstrait


2
@Silver J'ai lu la plupart de ce que vous avez tapé dans les blogs, mais j'essaie de comprendre pratiquement. J'ai fait des services WCF, des interfaces exposées (mais ce n'était qu'une seule application autonome sans en amont ni en aval). Par conséquent, je ne pouvais pas le comprendre correctement même si j'avais très bien conçu et implémenté des interfaces. Ma question est, pratiquement, vous partagez simplement les noms de méthode que signifie le contrat, n'est-ce pas? COMMENT CELA EST-IL UTILE: (Je sais que cela oblige simplement à implémenter toutes les méthodes, mais sinon comment? Dans votre article ci-dessus sur l'interface, le deuxième point dit partager, signifie que vous pouvez en donner un exemple pratique en temps réel
Apprenant

1
Pour un exemple pratique concernant les interfaces et SOA, nous partageons nos interfaces WCF ( DataContracts) dans un assembly .NET ( par exemple, Contracts.Shared.dll ) afin que les clients clients .NET puissent facilement interagir en utilisantChannelFactory (en évitant de générer du code via Ajouter une référence de service, etc. ) ou en utilisant Ajouter une référence de service avec des types partagés
SliverNinja - MSFT

Si, je ne déclare que des méthodes abstraites dans un calss abstrait, alors la classe abstraite agira comme une interface, alors pourquoi avons-nous besoin d'une interface?
Abhijit Ojha

25

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 savoir quoi que ce soit d'autre les uns sur les autres.


Cela a du sens, mais j'ai encore du mal à comprendre, pourriez-vous simplement ne pas créer une classe de base pour PowerSocket et toutes ces autres choses en héritent si nécessaire. Techniquement, les prises de courant n'ont aucune idée des autres classes.
altaaf.hussein

Je pense que l'héritage multiple n'est pas autorisé en C #
Hugh Seagraves

22

En un mot - à cause du polymorphisme !

Si vous «programmez sur une interface, pas sur une implémentation», vous pouvez injecter différents objets qui partagent la même interface (type) dans la méthode en tant qu'argument. De cette façon, le code de votre méthode n'est couplé à aucune implémentation d'une autre classe, ce qui signifie qu'il est toujours prêt à fonctionner avec des objets nouvellement créés de la même interface. (Principe d'ouverture / fermeture)

  • Examinez l'injection de dépendances et lisez définitivement Design Patterns - Elements of Reusable Object-Oriented Software by GOF.

4

C # n'a pas de typage canard - ce n'est pas parce que vous savez qu'une certaine méthode est implémentée dans un ensemble de classes concrètes que vous pouvez les traiter de la même manière en ce qui concerne l'appel de cette méthode. L'implémentation d'une interface vous permet de traiter toutes les classes qui l'implémentent comme le même type de chose, en ce qui concerne ce que définit cette interface.


3
Vous pouvez obtenir une sorte de ducktyping dans .net4 avec le type dynamique.
Tony Hopkinson

4

Je crois que beaucoup de sang a déjà été versé en posant ces questions, et beaucoup essaient de résoudre ces problèmes en expliquant des termes de type robot qu'aucun humain normal ne peut comprendre.

Alors d'abord. pour savoir pourquoi interface et pourquoi abstrait, vous devez savoir à quoi ils servent. J'ai personnellement appris ces deux en appliquant Factory Class. vous trouvez un bon tuturial sur ce lien

Maintenant, explorons le lien que j'ai déjà donné.

Vous avez une classe de véhicule qui peut changer selon les besoins de l'utilisateur (comme l'ajout d'un camion , d'un réservoir , d'un avion , etc.

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

et

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

et les deux ont le contrat IChoice qui dit simplement que ma classe devrait avoir la méthode d'achat

public interface IChoice
{
    string Buy();
}

Maintenant, vous voyez, cette interface applique uniquement la méthode Buy()mais laisse la classe héritée décider quoi faire lorsqu'elle l'implémente. C'est la limitation d'Interface, en utilisant purement interface, vous pourriez finir par répéter une tâche que nous pouvons implémenter automatiquement en utilisant abstact. Sur notre exemple, disons, l'achat de chaque véhicule a une réduction.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

Maintenant, en utilisant la classe d'usine, vous pouvez réaliser la même chose, mais en utilisant abstract, vous laissez la classe de base exécuter la Buy()méthode.

En résumé: les contrats d' interface permettent à la classe d'hériter de faire l'implémentation tandis que les contrats de classe abstraite peuvent initialiser l'implémentation (qui peut remplacer par la classe Inherit)


2

Avec une interface, vous pouvez effectuer les opérations suivantes:

1) Créez des interfaces séparées qui offrent différentes coupes de votre implémentation, permettant une interface plus cohérente.

2) Autorisez plusieurs méthodes avec le même nom entre les interfaces, car bon, vous n'avez aucune implémentation conflictuelle, juste une signature.

3) Vous pouvez effectuer des versions et supprimer votre interface indépendamment de votre implémentation, en vous assurant qu'un contrat est respecté.

4) Votre code peut s'appuyer sur l'abstraction plutôt que sur la concrétion, ce qui permet une injection de dépendances intelligente, y compris l'injection de Mocks de test, etc.

Il y a beaucoup d'autres raisons, j'en suis sûr, ce ne sont que quelques-unes.

Une classe abstraite vous permet d'avoir une base partiellement concrète à partir de laquelle travailler, ce n'est pas la même chose qu'une interface mais a ses propres qualités telles que la possibilité de créer une implémentation partielle en utilisant le modèle de méthode de modèle.


Vous avez négligé le plus important: implémenter une interface rend votre classe utilisable par tout code nécessitant une implémentation de cette interface, sans que le code en question ait à connaître quoi que ce soit sur votre classe.
supercat

2

En tant qu'échantillon réel de la réponse @ user2211290:

Les deux Arrayet Listont une interface IList. Ci-dessous, nous avons un string[]et un List<string>et vérifions les deux avec une méthode en utilisant IList :

string[] col1 = { "zero", "one", "two", "three", "four"};
List<string> col2 = new List<string>{ "zero", "one", "two", "three"};

//a methode that manipulates both of our collections with IList
static void CheckForDigit(IList collection, string digit)
{
    Console.Write(collection.Contains(digit));
    Console.Write("----");
    Console.WriteLine(collection.ToString()); //writes the type of collection
}

static void Main()
{
    CheckForDigit(col1, "one");   //True----System.String[]
    CheckForDigit(col2, "one");   //True----System.Collections.Generic.List`1[System.String]



//Another test:

    CheckForDigit(col1, "four");   //True----System.String[]
    CheckForDigit(col2, "four");   //false----System.Collections.Generic.List`1[System.String]
}

1

Vous ne pouvez hériter que d'une seule classe abstraite. Vous pouvez hériter de plusieurs interfaces. Cela détermine ce que j'utilise dans la plupart des cas.

L'avantage de la classe abstraite serait que vous pouvez avoir une implémentation de base. Cependant, dans le cas de IDisposable, une implémentation par défaut est inutile, car la classe de base ne sait pas comment nettoyer correctement les choses. Ainsi, une interface serait plus adaptée.


1

La classe abstraite et l'interface sont des contrats.

L'idée d'un contrat est que vous spécifiez un comportement. Si vous dites que vous avez mis en œuvre, vous avez accepté le contrat.

Le choix de l'abstrait sur l'interface est.

Tout descendant non abstrait de la classe abstraite implémentera le contrat.

contre

Toute classe qui implémente l'interface implémentera le contrat.

Vous utilisez donc abstract lorsque vous souhaitez spécifier un comportement que tous les descendants doivent implémenter et vous évitez de définir une interface distincte, mais maintenant tout ce qui répond à ce contrat effectivement agrégé doit être un descendant.


1

Les interfaces consistent à faire une abstraction (un archétype) de l'abstraction (les classes) de la réalité (les objets).

Les interfaces doivent spécifier les termes du contrat sans fournir l'implémentation fournie par les classes.

Les interfaces sont des spécifications:

  • Les interfaces sont des artefacts de conception pour spécifier le comportement immobile du concept car il est seul et statique.

  • Les classes sont des artefacts de temps de mise en œuvre pour spécifier la structure mobile de la réalité lorsqu'elle interagit et se déplace.

Qu'est-ce qu'une interface?

Lorsque vous observez un chat, vous pouvez dire que c'est un animal qui a quatre pattes, une tête, un tronc, une queue et des cheveux. Vous pouvez voir qu'il peut marcher, courir, manger et miauler. Etc.

Vous venez de définir une interface avec ses propriétés et ses opérations. En tant que tel, vous n'avez défini aucun modus operandi, mais uniquement des fonctionnalités et des capacités sans savoir comment les choses fonctionnent: vous avez défini des capacités et des distinctions.

En tant que tel, ce n'est pas encore vraiment une classe même si dans UML nous l'appelons une classe dans un diagramme de classes parce que nous pouvons définir des membres privés et protégés pour commencer à avoir une vue approfondie de l'artefact. Ne soyez pas confondu ici car en UML une interface est une chose légèrement différente d'une interface en C #: c'est comme un point d'accès partiel à l'atome d'abstraction. En tant que tel, nous avons dit qu'une classe peut implémenter plusieurs interfaces. En tant que tel, c'est la même chose, mais pas, car les interfaces en C # sont à la fois utilisées pour abstraire l'abstraction et pour limiter cette abstraction en tant que point d'accès. Ce sont deux utilisations différentes. Ainsi, une classe en UML représente une interface de couplage complète à une classe de programmation, alors qu'une interface UML représente une interface de découplage d'une section d'une classe de programmation. En effet, le diagramme de classes en UML ne prend pas en charge l'implémentation et tous ses artefacts sont au niveau de l'interface de programmation. Alors que nous mappons des classes UML à des classes de programmation, il s'agit d'une transposition d'abstraction abstraite en abstraction concrète. Il y a une subtilité qui explique la dichotomie entre le champ du design et le champ de la programmation. Ainsi, une classe en UML est une classe de programmation du point de vue d'une interface de programmation tout en considérant les choses cachées internes.

Les interfaces permettent également de simuler l'héritage multiple lorsqu'il n'est pas disponible de manière maladroite. Par exemple, la classe cat implémentera l'interface cat qui dérive elle-même de l'interface animal. Cette classe de chat implémentera également ces interfaces: marcher, courir, manger et faire un son. Cela compense l'absence d'héritage multiple au niveau de la classe, mais à chaque fois, vous devez tout réimplémenter et vous ne pouvez pas factoriser la réalité au mieux comme la réalité elle-même le fait.

Pour comprendre que nous pouvons nous référer au codage d'objets Pascal où vous définissez dans une unité l'interface et les sections d'implémentation. Dans l'interface, vous définissez les types et dans l'implémentation vous implémentez le type:

unit UnitName;

interface

type
  TheClass = class
  public
    procedure TheMethod;
  end;

implementation

class procedure TheClass.TheMethod;
begin
end;

Ici, la section interface correspond à la conception de la classe UML tandis que les types d'interfaces sont donc d'autres choses.

Donc, dans notre métier, nous avons un mot, interface , pour désigner deux choses distinctes mais similaires, et c'est une source de confusion.

Toujours en C # par exemple, les interfaces de programmation permettent de compenser l'absence de vrai polymorphisme générique sur les types ouverts sans vraiment réussir l'objectif car vous avez perdu l'habileté fortement typée.

Après tout, des interfaces sont nécessaires pour permettre à des systèmes incompatibles de communiquer sans se soucier de l'implémentation et de la gestion des objets en mémoire comme introduit avec le modèle d'objet commun (distribué).

Qu'est-ce qu'une classe?

Après avoir défini une réduction de la réalité d'un point de vue externe, vous pouvez ensuite la décrire d'un point de vue intérieur: c'est la classe où vous définissez le traitement des données et la gestion des messages pour permettre à la réalité que vous avez encapsulée de prendre vie et d'interagir grâce aux objets utilisant des instances.

Ainsi en UML vous réalisez une immersion fractale dans les roues de la machinerie et vous décrivez les états, les interactions etc. pour pouvoir implémenter l'abstraction du fragment de la réalité que vous voulez manipuler.

En tant que telle, une classe abstraite est en quelque sorte l'équivalent d'une interface du point de vue du compilateur.

Plus d'information

Protocole (programmation orientée objet)

C # - Interfaces

C # - Classes


1

Laissez-moi vous parler des grille-pain volants.

grille-pain volant

Il existe, bien sûr, de nombreuses situations dans lesquelles vous pouvez construire un système logiciel fonctionnel sans déclarer ni implémenter aucune interface: toute conception de logiciel orientée objet peut être réalisée en utilisant uniquement des classes.

Là encore, tout système logiciel peut également être implémenté en langage d'assemblage, ou mieux encore en code machine. La raison pour laquelle nous utilisons des mécanismes d'abstraction est qu'ils ont tendance à rendre les choses plus faciles. Les interfaces sont un tel mécanisme d'abstraction.

Ainsi, il se trouve qu'il existe certaines conceptions orientées objet non triviales qui sont tellement plus faciles à implémenter si vous utilisez des interfaces, que les interfaces deviennent pratiquement nécessaires dans ces cas.

Ces conceptions non triviales ont à voir avec l'héritage multiple, qui, dans sa «vraie» forme, se produit lorsqu'une classe hérite non pas d'une seule classe de base, mais de deux classes de base ou plus. Cette vraie forme n'est pas possible en C #, mais avant que des langages comme C # et Java n'entrent en vigueur, le langage qui régnait était le C ++, qui prend entièrement en charge le véritable héritage multiple. Malheureusement, le véritable héritage multiple s'est avéré ne pas être une très bonne idée, car il complique énormément la conception du langage, et il donne également lieu à divers problèmes, par exemple le fameux "Diamond Problem". (Voir "Quel est le problème exact de l'héritage multiple?" Réponse de J Francis )

Donc, si quelqu'un voulait construire une classe «grille-pain volant», il hériterait d'une classe «grille-pain» existante et aussi d'une classe «grille-pain» existante. Le type de problème auquel ils étaient susceptibles de se heurter était que l'alimentation de la classe grille-pain était probablement une prise murale, tandis que l'alimentation de la classe des machines volantes était susceptible d'être de la nourriture pour pigeons, et la nouvelle classe résultante serait soit en quelque sorte avoir les deux, ou on ne sait pas lequel il aurait. (Le problème du diamant.)

Les créateurs de langages comme C # et Java ont décidé de ne pas autoriser un véritable héritage multiple, afin de garder le langage simple et d'éviter les pièges comme le Diamond Problem. Cependant, une certaine forme d'héritage multiple est toujours nécessaire (ou du moins très souhaitable), donc dans ces langages, ils ont introduit des interfaces comme un moyen de prendre en charge une forme moindre d'héritage multiple tout en évitant les problèmes et la complexité d'un véritable héritage multiple.

Dans cette forme moindre d'héritage multiple, vous n'êtes pas autorisé à avoir une classe qui hérite de plusieurs classes de base, mais vous pouvez au moins hériter d'une ou plusieurs interfaces. Donc, si vous voulez construire un grille-pain volant, vous ne pouvez pas hériter à la fois d'une classe de grille-pain existante et d'une classe de vol existante, mais ce que vous pouvez faire est d'hériter d'une classe de grille-pain existante, puis d'exposer une interface volante que vous implémentez vous-même, éventuellement en utilisant tout moyen dont vous avez déjà hérité du grille-pain.

Ainsi, à moins que vous ne ressentiez le besoin de créer une classe qui regroupe deux ensembles de fonctionnalités différents et non liés, vous n'aurez besoin d'aucune forme d'héritage multiple, vous n'aurez donc pas besoin de déclarer ou d'implémenter des interfaces.


0

Les interfaces permettent au concepteur de classe de rendre les méthodes disponibles très claires pour l'utilisateur final. Ils font également partie intégrante du polymorphisme.


Bien dit sur votre première déclaration. Mais je ne comprends pas votre deuxième déclaration, pourriez-vous s'il vous plaît élaborer avec un exemple en temps réel s'il vous plaît?
Apprenti

0

Je ne publierai pas la définition d'une interface par rapport à une classe abstraite car je pense que vous connaissez très bien la théorie et je suppose que vous connaissez les principes SOLID, alors soyons pratiques.

Comme vous le savez, les interfaces ne peuvent pas avoir de code, donc les inconvénients sont assez simples à comprendre.

si vous avez besoin d'initialiser la propriété de votre classe en fournissant un constructeur ou si vous souhaitez fournir une partie de l'implémentation, une classe abstraite conviendrait parfaitement à une interface qui ne vous permettrait pas de le faire.

Donc, en général, vous devriez préférer la classe abstraite aux interfaces lorsque vous devez fournir un constructeur ou tout code au client qui héritera / étendra votre classe


-2

Les classes abstraites sont créées pour les entités liées alors que les interfaces peuvent être utilisées pour les entités non liées.

Par exemple, si j'ai deux entités dites Animal et Humain, alors je vais opter pour Interface où, comme si je devais aller en détail, dire Tigre, lion et vouloir être en relation avec Animal, alors je choisirai la classe Animal Abstract.

ressemblera à ci-dessous

   Interface             
   ____|____
  |        |
Animal   Human



  Animal (Abstract class)
   __|___
  |      |
Tiger   Lion
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.