web-dev-qa-db-fra.com

Vous ne savez pas quand utiliser une propriété abstraite ou non

Je ne sais pas vraiment ce qui est le mieux, ni quand utiliser réellement dans les classes et propriétés abstraites, ni quand utiliser des propriétés non abstraites. Je vais essayer de faire un exemple simple. Disons que j'ai ceci:

abstract class Human
{
  public GenderType Gender { get; set; }
  public string Name { get; set; }
  public Date Born { get; set; }
  public bool IsNerd { get; set; }

  abstract public void Speak();
  abstract public void Sleep();
  abstract public void AnoyingPeopleOnStackOverflow();
  //... so on
}

class Peter : Human
{
  //Peter is special, he got a second name
  //But thats all, everything else is the same as like on other humans
  public string SecondName { get; set; }

  //...override abstract stuff
}

Est-ce que ça va? Si j'ai bien compris, je n'ai pas besoin d'utiliser une propriété abstraite si je ne veux pas la remplacer. Et dans cette situation, tout irait bien, seules les méthodes telles que Speak, Sleep et ainsi de suite devraient être abstraites.

Maintenant, si cela vous convient, quand utiliserais-je ou devrais-je utiliser une propriété abstraite?

35
miri

Utilisez une propriété abstraite lorsque vous n'avez pas d'implémentation par défaut et que les classes dérivées doivent l'implémenter.

Utilisez une propriété virtuelle lorsque vous avez une implémentation dans la classe de base mais que vous souhaitez autoriser le remplacement.

Utilisez le mot clé override pour remplacer un membre. Marquez le membre avec sealed override s'il ne doit pas être remplacé à nouveau.

Ne marquez pas la propriété comme étant abstract ou virtual si vous ne voulez pas qu'elle soit remplacée.

Utilisez le mot clé new pour masquer un membre non abstrait, non virtuel (c'est rarement une bonne idée).

Comment: définir des propriétés abstraites

Je trouve que les propriétés abstraites apparaissent souvent dans une conception, ce qui implique qu'elles auront une logique et/ou des effets secondaires spécifiques au type. Vous dites fondamentalement "voici un point de données que toutes les sous-classes doivent avoir, mais je ne sais pas comment le mettre en œuvre". Cependant, les propriétés contenant beaucoup de logique et/ou provoquant des effets indésirables peuvent ne pas être souhaitables. Ceci est une considération importante, bien qu’il n’existe pas de méthode bien ou mal pour le faire.

Voir:

Personnellement, je trouve que j'utilise fréquemment des méthodes abstraites, mais rarement des propriétés abstraites.

68
Tim Medora

Je sais ce que je veux qu'ils fassent, peu importe comment ils le font: Interface.

Je sais ce que je veux qu'ils fassent, je ne me soucie pas de savoir comment ils font certaines choses, mais j'ai une idée précise de la façon dont ils vont (ou du moins la plupart d'entre eux) faire d'autres choses: cours abstrait.

Je sais ce que je veux qu'ils fassent et comment la plupart d'entre eux le feront: cours concret avec des membres virtuels.

Vous pouvez avoir d’autres cas tels que, par exemple, une classe abstraite sans membres abstraits (vous ne pouvez pas en avoir une instance, mais les fonctionnalités qu'elle offre, elle offre tout à fait), mais elles sont plus rares et se produisent normalement car une hiérarchie particulière s'offre de manière nette et flagrante à une donnée donnée. problème.

(Incidemment, je ne penserais pas à Peter comme un type d'humain, mais à chaque peter comme un exemple d'humain qui s'appelle Peter. Ce n'est pas vraiment juste de choisir un exemple de code de cette manière, mais quand vous ' repenser à ce type de problème est plus pertinent que d’habitude).

27
Jon Hanna

Les membres abstraits sont simplement des membres virtuels que vous devez remplacer. Vous utilisez ceci pour quelque chose qui doit être implémenté, mais ne peut pas être implémenté dans la classe de base.

Si vous voulez créer une propriété virtuelle et que vous voulez qu'elle soit remplacée dans la classe qui hérite de votre classe, vous devez en faire une propriété abstraite.

Si, par exemple, vous avez une classe d’animaux, sa capacité à respirer ne serait pas possible uniquement à partir de l’information qu’il s’agissait d’un animal, mais c’est quelque chose de très important:

public abstract class Animal {

  public abstract bool CanBreathe { get; }

}

Pour un poisson et un chien, la mise en œuvre serait différente:

public class Dog : Animal {

   public override bool CanBreathe { get { return !IsUnderWater; } }

}

public class Fish : Animal {

   public override bool CanBreathe { get { return IsUnderWater; } }

}
13
Guffa

Utilisez abstract lorsque toutes les sous-classes ont pour implémenter la méthode/propriété. S'il n'est pas nécessaire que chaque sous-classe l'implémente, ne l'utilisez pas. 

En ce qui concerne votre exemple, si SecondName n'est pas requis pour chaque personne, il n'est pas nécessaire de créer une propriété abstraite dans la classe de base. Si, par contre, chaque personne a besoin d'un deuxième nom, faites-en une propriété abstraite.

Exemple d'utilisation correcte d'une propriété abstraite:

public class Car
{
    public abstract string Manufacturer { get; }
}

public class Odyssey : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Honda";
         }
    }
}

public class Camry : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Toyota";
         }
    }
}

Faire Maker résumé est correct car every car a un constructeur et doit pouvoir dire à l'utilisateur qui est ce constructeur. 

4
Daniel

Une propriété abstraite serait utilisée là où vous voulez que la classe expose toujours la propriété, mais où vous ne pouvez pas cerner l'implémentation de cette propriété - en la laissant à/forcer la classe héritante à le faire.

Il existe un exemple ici , dans lequel la classe abstraite s'appelle Shape et expose une propriété abstract Area. Vous ne pouvez pas implémenter la propriété Area dans la classe de base, car la formule de surface changera pour chaque type de forme. Toutes les formes ont une zone (de quelque sorte), donc toutes les formes doivent exposer la propriété.

Votre implémentation elle-même a l'air bien. J'essayais de penser à un exemple raisonnable d'une propriété abstraite pour un Human, mais je ne pouvais penser à rien de raisonnable.

1
Jon Egerton