Question

J'ai commencé avec une interface générique appelée ILogin. Les interfaces requièrent l'implémentation de deux propriétés: UserID et Password. J'ai plusieurs classes de type login qui implémentent cette interface. Au fur et à mesure que mon projet grandissait, j'ai constaté que de nombreuses classes répétaient le code d'utilisateur et le mot de passe. Maintenant, je décide que j'ai besoin d'une classe de connexion de base.

Est-il approprié de créer une classe de connexion abstraite de base abstraite qui implémente l'interface ILogin et de laisser toutes mes classes concrètes hériter de la classe abstraite et remplacer si nécessaire? Au départ, je pensais que cela ne poserait aucun problème. Ensuite, j'ai commencé à penser qu'ILogin n'était probablement pas nécessaire, car il ne sera probablement jamais implémenté que par ma classe abstraite.

Y a-t-il un avantage à conserver à la fois la classe abstraite et l'interface?

Merci!

Était-ce utile?

La solution

Certainement. Pensons à un exemple concret.

Disons que nous avons une classe abstraite Animal . Nous allons créer des sous-classes Cat , Chien , Mosquito et Eagle . Nous pouvons implémenter ses méthodes Eat () , Breathe () , Sleep () de la classe abstraite Animal .

Jusqu'ici, tout va bien. Maintenant, supposons que nous voulions avoir la méthode Fly () pour les classes Mosquito et Eagle . Étant donné que ces deux organismes ne sont pas vraiment liés (l'un est un oiseau, l'autre est un insecte), il ne serait pas facile de trouver un ancêtre commun aux deux que nous pouvons avoir en tant que classe abstraite. Cela serait mieux mis en œuvre par une interface IFly .

L'interface IFly peut avoir une méthode Fly () à implémenter. Les classes Mosquito et Eagle peuvent toutes deux être des sous-classes de la classe abstraite Animal et implémenter l'interface IFly et pouvoir pour manger () , respirer () , mettre en veille () et voler () sans avoir de type impair relation ancestrale entre les deux classes.

Autres conseils

Je code généralement contre les classes abstraites quand il est judicieux de mettre en œuvre (et de créer dans un contrat externe assemblage / bibliothèque) une interface dans chaque classe (abstraite ou non) afin de pouvoir implémenter plus facilement Windows Communication Foundation ou inversion du contrôle lorsque cela est nécessaire (ce qui est presque toujours pour se moquer). Cela est devenu une seconde nature pour moi.

Absolument. L’interface est toujours la bonne façon de procéder. Ainsi, tout le monde peut l’implémenter (y compris quelque chose qui a déjà un parent).

La classe abstraite a tendance à faire en sorte que vous n'ayez pas à réimplémenter certains éléments de cette fonctionnalité. Swing l'utilise un peu, ils auront une interface et ensuite une implémentation par défaut pour vous permettre de remplacer une seule des 5 méthodes, ou bien l'ajout d'écouteurs peut être pris en charge, mais vous n'avez pas à utiliser cette classe de base si vous le souhaitez. je ne veux pas.

Si votre classe abstraite est la seule classe qui implémentera jamais l'interface, vous pouvez toujours vérifier les occurrences de la classe abstraite, vous n'avez pas besoin de l'interface. Toutefois, si vous souhaitez être compatible avec de nouvelles classes non encore écrites, qui n’élargiront pas la classe abstraite mais qui pourraient utiliser l’interface, continuez à utiliser cette interface maintenant.

Je suis d'accord avec cfeduke. Je commence TOUJOURS avec les interfaces et, dans le passé, j'ai utilisé des classes abstraites qui implémentent des interfaces et fournissent des fonctionnalités de base pour promouvoir la réutilisation du code parmi les classes héritées de la classe abstraite. Mocking et IOC sont généralement dépendants de l'interface, c'est pour cette raison que j'utiliserais des interfaces dans mes conceptions.

Si la classe abstraite a une fonctionnalité, il est sage de la conserver. Mais s'il ne contient que des méthodes abstraites et aucun champ. Je ne vois aucune utilité à garder les deux.

Modifier: Je travaille sur du code existant avec de nombreuses classes abstraites. Si j'ai le temps, je vais ajouter les interfaces (et éventuellement supprimer les résumés vides). Parce que travailler avec des interfaces augmente considérablement les possibilités. Et ils honorent leur nom en définissant exactement l’interface.

Votre interface définit le contrat à remplir pour que l'objet soit accepté. votre classe abstraite définit le contrat qui doit être rempli ET définit certains détails d’implémentation spécifiques.

Pensez-y de cette façon. si vous pensez qu'il est toujours possible pour quiconque de remplir ce contrat autrement que par la manière esquissée par la classe abstraite (par exemple, avec une implémentation de type de données de support différente), vous devez avoir à la fois l'interface et la classe abstraite met en œuvre que.

La classe abstraite et l'interface ne nécessitent quasiment pas de surcharge. votre risque avec cette approche implique principalement qu'un codeur récent rencontre l'interface, ne réalisant pas qu'il existe une classe abstraite qui l'implémente, et crée une implémentation complète à partir de rien, là où ce n'est pas nécessaire. Je dirais que cela pourrait être contourné en spécifiant dans la documentation de votre interface qu’il existe un "défaut". implémentation de l'interface dans votre classe abstraite; Bien que certaines normes de codage puissent faire fausse route à ce sujet, je ne vois pas de réel problème.

Je vous conseillerais toujours d'utiliser des interfaces. Les classes abstraites présentent l'avantage que vous pouvez ajouter à la fonctionnalité par défaut, mais obliger un utilisateur à utiliser son héritage unique est plutôt agressive.

Les bibliothèques de classes Microsoft privilégient les classes abstraites aux interfaces dans un certain nombre de cas, car cela leur permet de modifier la classe sous-jacente. L'ajout d'une méthode à une classe abstraite interrompt rarement la tâche de quelqu'un qui en hérite. L'ajout d'une méthode à une interface casse toujours ses implémenteurs. Cependant, cela constitue l’une des meilleures raisons d’utiliser des interfaces: la possibilité terrible que Microsoft ait déjà utilisé votre héritage.

Je suggérerais toutefois que, dans votre cas particulier, vous souhaitiez peut-être revenir sur le motif de conception que vous utilisez. Il semble inhabituel d’avoir beaucoup de " type de connexion " classes.

Je pense qu'un des avantages de conserver l'interface serait la possibilité pour les futures classes d'implémenter plusieurs interfaces, alors qu'une classe ne peut hériter que d'une classe abstraite.

Vous pouvez étendre les fonctionnalités des sous-classes en créant une nouvelle interface avec un ensemble de méthodes différent.

En supposant que vous demandez spécifiquement quand l'interface et la classe abstraite ont des signatures identiques ...

... (Si les membres de l'interface diffèrent de quelque façon que ce soit des membres de la classe abstraite, la réponse est bien sûr que oui, il se peut que les deux soient nécessaires)

... mais en supposant que les membres soient identiques, la seule raison pour laquelle je pense avoir besoin des deux est que si vous codez dans un système ne permettant pas l'héritage à plusieurs implémentations, il existe deux classes dans votre système qui doivent être polymorphiquement similaires, mais doivent hériter de différentes classes de base ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top