Conception de l'héritage à l'aide de la classe Interface + abstract. Bonnes pratiques?
Je ne suis pas vraiment sûr de savoir comment le titre de cette question, mais, fondamentalement, j'ai une interface comme ceci:
public interface IFoo
{
string ToCMD();
}
un couple de absract classes qui implémentent IFoo comme:
public abstract class Foo : IFoo
{
public abstract string ToCMD();
}
public abstract class Bar : IFoo
{
public abstract string ToCMD();
}
puis les classes qui héritent de Foo et Bar:
public class FooClass1 : Foo
{
public override string ToCMD()
{return "Test";}
} ///there are about 10 foo classes.
public class BarClass : Bar
{
public override string ToCMD()
{return "BarClass";}
} ///about the same for bar classes.
Je fais cela, de sorte que lorsque j'ai ma liste personnalisée comme:
public class Store<T> : List<T> where T : IFoo {}
Je peux restreindre les types qui vont dans il mais en ayant l'interface, il faudra tout type de IFoo.
Quelque chose comme:
Store<Foo> store = new Store<Foo>(); //Only Foo types will work.
store.Add(new FooClass1()); //Will compile.
Store<IFoo> store = new Store<IFoo>(); //All IFoo types will work.
store.Add(new FooClass1()); //Will compile.
store.Add(new BarClass()); //Will compile.
Ma question est: Est-ce un ok façon d'aller à ce sujet? ou est-il un meilleur moyen?
EDIT: l'Image->
source d'informationauteur Nathan W
Vous devez vous connecter pour publier un commentaire.
La nécessité d'une chaîne d'héritage est discutable, en général.
Cependant le scénario précis de la combinaison d'une classe de base abstraite avec une interface.. je le vois de cette façon:
Si vous avez une classe de base abstraite comme cela, vous devriez également avoir une interface correspondante. Si vous disposez d'une interface, puis utilisez la classe de base abstraite seulement où l'héritage de la chaîne est sensible.
Cela dit, si je suis en train d'écrire une bibliothèque et c'est une partie de mon API/Framework, je comprend généralement un "défaut de mise en œuvre" qui peut être utilisée comme classe de base. Il mettra en œuvre les méthodes d'interface dans un de naïf, de façon générale, lorsque cela est possible, et laisser le reste aux héritiers, mettre en oeuvre et remplacer au besoin.
C'est juste une commodité de la bibliothèque si la, pour aider les personnes qui veulent mettre l'interface en fournissant une fonctionnelle exemple qui peut couvrir la plupart de ce dont ils ont besoin pour mettre en œuvre déjà.
En bref, l'interface est plus précieux que la classe de base, mais une classe de base peut économiser beaucoup de temps et de réduire les buggy implémentations d'interface.
Bien, c'est ce que le mot-clé where. Vous avez probablement besoin d'évaluer votre modèle d'objet pour s'assurer que la profondeur de votre héritage est nécessaire. Profondeur des hiérarchies d'héritage ont tendance à compliquer les projets et sont généralement un drapeau rouge, mais cela dépend de la situation.
Normalement, vous n'avez pas besoin de la classe abstraite pour retirer la fonctionnalité dont vous parlez avec les listes, et les interfaces sont le "préféré" la méthode pour spécifier le type de restrictions. J'avais seulement utiliser la version abstraite de votre classe, il est commun de fonctionnalités que vous souhaitez pour encapsuler.
Réponse courte: assurez-vous que vous n'allez pas l'héritage de fou.
Espère que ça aide!
Vous pourriez tout aussi bien utiliser des interfaces. Il n'y a pas de raison d'utiliser une classe abstraite.
vous avez besoin de l'interface; vous pouvez ou ne pouvez pas besoin de la classe abstraite.
en général, si vous pouvez apporter des éléments utiles comportement dans une classe de base, puis de fournir une classe de base; si la classe de base n'est pas complète par elle-même, puis le rendre abstrait (MustInherit en langage VB)
sinon, l'interface est suffisamment
Je ne suis pas sûr si c'est ce que vous cherchez, mais peut-être ce que vous voulez faire est de la ferraille de l'interface, tous ensemble, et de faire cela:
J'espère que vous avez d'autres membres de la
Foo
etBar
classes! Cela vous permettra de limiter votre collection personnalisée parBase
ou tout simplement utiliser une plaineList<Base>
.