Question

Si vous souhaitez hériter d'une classe de base pour des fonctionnalités communes à plusieurs classes, devez-vous implémenter cette classe à l'aide d'une classe ou d'une classe abstraite?

Était-ce utile?

La solution

Cela dépend, si vous ne voulez jamais pouvoir instancier la classe de base, alors rendez-la abstraite. Sinon, laissez-le comme une classe normale.

Autres conseils

Si la classe de base ne doit pas être instanciée, faites-en une classe abstraite. Si la classe de base doit être instanciée, ne la rendez pas abstraite.

Dans cet exemple, il est logique de rendre abstraite la classe de base car celle-ci n'a pas de signification concrète:

abstract class WritingImplement
{
    public abstract void Write();
}

class Pencil : WritingImplement
{
    public override void Write() { }
}

Cependant, dans cet exemple suivant, vous pouvez voir comment la classe de base a une signification concrète:

class Dog
{
    public virtual void Bark() { }
}

class GoldenRetriever : Dog
{
    public override void Bark() { }
}

Tout cela est vraiment subjectif - vous devriez être capable de faire un très bon jugement en fonction des besoins de votre domaine particulier.

Cela dépend. Cela a-t-il un sens que la classe de base en question existe seule sans en être dérivée? Si la réponse est oui, alors ce devrait être une classe normale, sinon ce devrait être une classe abstraite.

Je suggère:

  • Créer une interface.
  • Implémentez l'interface dans votre classe de base.
  • Faites de la classe de base une vraie classe, pas abstraite (voir pourquoi ci-dessous).

La raison pour laquelle je préfère les classes réelles aux classes abstraites est que les classes abstraites ne peuvent pas être instanciées, ce qui limite les options futures inutilement . Par exemple, il se peut que j'aie besoin ultérieurement de l'état et des méthodes fournis par la classe de base, mais que je ne puisse pas hériter ni implémenter l'interface; si la classe de base est abstraite, je n'ai pas de chance, mais si la classe de base est une classe ordinaire, je peux créer une instance de la classe de base et la conserver en tant que composant de mon autre classe, et déléguer à l'instance la possibilité de réutiliser la état / méthodes fournies.

Oui, cela n'arrive pas souvent, mais le but est: rendre l'abstrait de la classe de base empêche ce genre de réutilisation / solution, quand il n'y a aucune raison de le faire.

Maintenant, si instancier la classe de base serait dangereux, rendez-le abstrait - ou préférez-le moins, si possible; -)

Pensez-y comme à un compte bancaire:

Vous pouvez créer un compte de base abstrait générique appelé "Compte", qui contient des informations de base telles que les détails du client.

Vous pouvez ensuite créer deux classes dérivées appelées "SavingAccount". ou " DebitAccount " qui peut avoir son propre comportement tout en bénéficiant du comportement de la classe de base.

Il s’agit d’une situation dans laquelle le client doit avoir soit un compte d’épargne, soit un compte de débit, un compte générique "Compte". n’est pas autorisé car il n’est pas très populaire dans le monde réel d’avoir un compte sans description.

Si vous pouvez créer un scénario similaire pour vos besoins, résumé est le chemin à parcourir.

Les classes abstraites sont destinées aux classes partiellement implémentées.

En soi, cela n'a pas de sens d'avoir une instance d'une classe abstraite, elle doit être dérivée. Si vous souhaitez pouvoir créer la classe de base, elle ne peut pas être abstraite.

J'aime penser aux classes abstraites comme à des interfaces dont certains membres sont prédéfinis car ils sont communs à toutes les sous-classes.

Pensez-y d'une manière différente

  

Ma classe de base est-elle un objet complet?

Si la réponse est non, alors abstenez-vous. Si c'est oui, alors vous voudrez probablement en faire une classe concrète.

Je dirais que si vous ne prévoyez pas d'appeler la classe de base par elle-même, vous devez la définir comme une classe abstraite.

Cela dépend si vous voulez que la classe de base soit implémentée seule ou non.

En tant que classe abstraite, vous ne pouvez pas en créer d'objets.

Les classes abstraites sont idéales pour les fonctionnalités prédéfinies, par exemple: connaître le comportement exact minimum qu'une classe doit exposer, mais pas les données qu'elle doit utiliser pour le faire ou l'implémentation exacte.

abstract class ADataAccess
{
    abstract public void Save();
}

Les classes normales (non abstraites) peuvent être utiles pour des choses similaires, mais vous devez connaître les spécificités de l'implémentation pour pouvoir les écrire.

public class DataAccess
{
    public void Save()
    {
        if ( _is_new )
        {
            Insert();
        }
        else if ( _is_modified )
        {
            Update();
        }
    }
}

Vous pouvez également utiliser des interfaces (individuellement ou sur des classes, abstraites ou non) pour définir le même type de définition de prototype.

interface ISaveable
{
    void Save();
    void Insert();
    void Update();
}

class UserAccount : ISavable
{
    void ISavable.Save() { ... }
    void ISavable.Insert() { ... }
    void ISavable.Update() { ... }
}

Encore une autre option peut-être utiliser des génériques

class GenDataAccess<T>
{
    public void Save()
    {
        ...
    }
}

Toutes ces méthodes peuvent être utilisées pour définir un certain prototype avec lequel les classes peuvent travailler. Façons de vous assurer que le code A peut parler au code B. Et bien sûr, vous pouvez mélanger et assortir tout ce qui précède à votre guise. Il n’existe pas de méthode correcte, mais j’aime définir des interfaces et des classes abstraites, puis me référer aux interfaces. De cette façon, certaines des exigences de pensée relatives à la "plomberie" sont éliminées. dans les classes de niveau supérieur tout en gardant le maximum de flexibilité. (avoir des interfaces supprime la nécessité d'utiliser la classe de base abstraite, mais la laisse comme option).

Je pense que beaucoup d’entre vous devraient à nouveau suivre les cours OO de base.

Le principe de base de OOA / OOD est d’abréger l’abstrait abstrait, jusqu’à ce que vous ne puissiez plus en résumer. Si ce que vous regardez est une abstraction, qu’il en soit ainsi, c’est ce que votre OOA / OOD vous a déjà dit. Cependant, si vous êtes assis là à vous demander si " code " devrait être abstrait ou non, alors vous ne savez évidemment pas ce que le terme signifie et devriez aller réapprendre les bases OOA / OOD / OOP: -)

Plus précisément, vous devriez apprendre les motifs de conception et la théorie harmonique, cela aidera énormément avec vos conceptions OO!

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