Je dois expliquer à certains étudiants l'utilisation des classes abstraites et des interfaces, comme j'ai une formation très technique, j'aimerais savoir si vous m'aideriez à définir une explication facile pour junior.
Définition simple:
À quoi servent les classes abstraites, les interfaces et quelle est la différence entre les deux?
Quand est-il approprié d'utiliser l'un au lieu de l'autre?
Merci.
Je vais voir si je peux le faire avec une terminologie générique sans trop agiter la main.
Une interface est comme un contrat. Il indique qu'une classe qui implémente l'interface accepte d'implémenter toutes les fonctions déclarées (sous forme de signatures uniquement; pas de définition de fonction) par cette interface. La classe peut le faire de la manière qu'elle souhaite et fournir toute autre fonctionnalité, tant qu'elle implémente chacune des fonctions déclarées. Une interface est utile lorsque vous souhaitez pouvoir utiliser certaines fonctionnalités communes de classes qui ne sont pas liées par ailleurs - elles ne partagent aucun détail d'implémentation, uniquement les signatures de fonction. En C #, les déclarations de fonctions dans un interface
sont implicitement du virtuel pur.
Une classe abstraite est une classe partiellement définie qui ne peut pas être instanciée . Il comprend (généralement) une certaine implémentation, mais laisse certaines fonctions comme pure virtuelle - déclarées uniquement par leur signature. Les fonctions virtuelles pures ne sont pas définies dans la classe qui les déclare, elles doivent donc être implémentées par une sous-classe (sauf s'il s'agit également d'une classe abstraite). Seule une sous-classe qui définit toutes les fonctions virtuelles pures peut être instanciée. Le but d'une classe abstraite est de définir un comportement commun qui peut être hérité par plusieurs sous-classes, sans implémenter la classe entière. En C #, le mot clé abstract
désigne à la fois une classe abstraite et une méthode virtuelle pure.
En termes pratiques, la différence entre les deux est qu'une interface ne définit que des fonctions virtuelles pures, tandis qu'une classe abstraite peut également inclure des fonctions concrètes, des membres ou tout autre aspect d'une classe.
Une interface dit à l'utilisateur que cette classe supportera ces fonctions.
Par exemple:
public interface IWorker
{
void DoWork();
}
public class MyInformation : IWorker
{
public void DoWork()
{
//Do your class-specific Work
}
}
var info = new MyInformation();
info.DoWork();
Vous pourriez vous demander ici - pourquoi ne pas simplement ajouter la méthode dans MyInformation, au lieu d'implémenter une interface?
Voici une situation où cela serait utile:
List<IWorker> workers = GetWorkers();
foreach(var worker in workers)
worker.DoWork();
Ici, nous ne savons pas quel type d'objets nous recevons. Tout ce que nous savons, c'est qu'ils implémenteront l'une des méthodes définies dans IWorker. Peu nous importe comment ils le font - tout ce qui nous importe, c'est qu'ils soutiennent votre appel.
Quant à une classe abstraite:
public abstract class Serializer
{
protected void GetAttributes()
{
//Some default implementation
}
public abstract void SaveObject(String outputPath);
}
Nous avons une classe sérialiseur, qui a quelques implémentations par défaut de base - mais en soi, elle ne fait rien. Il ne sait pas comment écrire la sortie - seulement comment obtenir les informations d'attribut.
Vous pouvez maintenant avoir une implémentation concrète telle que:
public class XmlSerializer : Serializer
{
public override void SaveObject(String outputPath)
{
//Do your xml serializing
}
}
Ce qui le sérialisera en XML.
Encore une fois, vous ne vous souciez pas de la façon dont ils sérialisent, seulement qu'ils le fassent;
List<Serializer> serializers = GetWorkers();
foreach(var serializer in serializers)
serializer.SaveObject(@"C:\out.tmp");
Les interfaces sont comme des squelettes. Si vous voulez construire un humain, vous devez utiliser ce squelette.
Les interfaces créent simplement une sorte de structure pour vos classes pour indiquer que votre classe doit avoir une structure définie et convenue. Par exemple, tous les animaux font pipi, mangent et émettent des sons. Ainsi, vous pouvez avoir une interface, appelée IAnimal
qui mentionne uniquement que les classes doivent Pee
, Eat
et MakeSound
.
Les interfaces sont comme de simples listes de contrôle, qui devraient être implémentées totalement ou aucune. Lorsque vous voulez utiliser l'interface IAnimal
, c'est comme si votre patron vous disait "Hé, ne créez pas de classe Cat à moins que vous n'écriviez des méthodes pour manger, faire pipi et faire du son".
Les classes abstraites sont comme des squelettes, mais avec de la viande aussi. Il est juste là pour vous faciliter le travail.
Vous pouvez considérer une classe abstraite comme une interface, qui a déjà une certaine implémentation.
C'était la réponse anglaise simple. Mais après avoir obtenu cela, veuillez étudier davantage, pour obtenir le vrai concept.
J'essaierai d'être simple.
Une classe abstraite est une classe. Il est spécial en ce que vous ne pouvez pas créer d'objet de classe abstraite. Une classe non abstraite dans la classe dite concrète.
Une classe abstraite, étant une classe, peut contenir des éléments habituels comme des champs, des propriétés, des événements de méthodes, des indexeurs, etc. implémentations (par exemple méthodes sans corps).
Une interface est une description des membres qu'une autre classe aura à coup sûr. L'interface C # peut décrire uniquement les méthodes, les propriétés, les indexeurs et les événements.
Si une classe implémente une interface, elle doit implémenter tous les membres décrits par l'interface.
Cela signifie que si une classe, implémentant une interface, n'implémente pas tous les membres décrits par cette interface, alors cette classe doit être une classe abstraite!
Une classe abstraite peut être une classe "à moitié cuite", ce qui signifie qu'elle a fourni peu de méthodes avec corps, mais peu de méthodes sont sans corps, etc. Une interface ne peut jamais implémenter un membre qu'elle décrit.
La classe abstraite participe à la hiérarchie des classes basée sur l'héritage. Notez qu'en C #, une classe peut avoir au plus une classe parent qui peut être abstraite ou non.
Une classe peut implémenter plusieurs interfaces en même temps.
Il existe de nombreux cas d'utilisation pour les deux.
Les déclarations suivantes devraient vous donner plus de clarté:
Ni l'interface ni la classe abstraite ne peuvent être instanciées.
La classe peut hériter de zéro ou d'une classe (abstraite ou concrète).
L'interface peut hériter de zéro ou plusieurs interfaces.
L'interface ne peut pas hériter d'une classe.
La classe abstraite peut avoir des membres avec implémentation.
L'interface ne peut avoir aucun membre avec implémentation.
Pour être concret, la classe doit implémenter tous les membres dans l'interface.
J'espère que ça aide.