web-dev-qa-db-fra.com

Quelle est l'utilisation de 'abstract override' en C #?

Par simple curiosité, j'ai essayé de remplacer une méthode abstraite dans la classe de base et d’aborder l’abstrait d’implémentation. Comme ci-dessous:

public abstract class FirstAbstract
{
    public abstract void SomeMethod();
}

public abstract class SecondAbstract : FirstAbstract
{
    public abstract override void SomeMethod();
    //?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}

Curieux de savoir pourquoi le compilateur C # permet l’écriture de «substitution abstraite». N'est-ce pas redondant? Devrait être une erreur de compilation de faire quelque chose comme ça. Cela sert-il à un cas d'utilisation?

Merci de votre intérêt.

46
Manish Basantani

Il existe un exemple utile pour cela sur MSDN - vous pouvez forcer une classe dérivée à fournir une nouvelle implémentation pour une méthode.

public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

Si une méthode virtuelle est déclarée abstraite, elle est toujours virtuelle pour tout classe héritant de la classe abstraite. Une classe héritant d'un méthode abstraite ne peut pas accéder à la mise en oeuvre originale du fichier méthode: dans l'exemple précédent, DoWork de la classe F ne peut pas appeler DoWork sur la classe D. De cette manière, une classe abstraite peut forcer des classes dérivées pour fournir de nouvelles implémentations de méthodes pour les méthodes virtuelles.

58
BrokenGlass

Je le trouve vraiment utile pour assurer la bonne implémentation de ToString() dans les classes dérivées. Supposons que vous ayez une classe de base abstraite et que vous souhaitiez réellement que toutes les classes dérivées définissent une implémentation signifiante de ToString() parce que vous l'utilisez activement. Vous pouvez le faire très élégamment avec abstract override:

public abstract class Base
{
    public abstract override string ToString();
}

Il est clair pour les développeurs que ToString() sera utilisé d'une manière ou d'une autre dans la classe de base (comme l'écriture de la sortie pour l'utilisateur). Normalement, ils ne penseraient pas à définir cette dérogation.

43
ghord

Il est intéressant de noter que la version Roslyn du compilateur C # contient une méthode de substitution abstraite, que j’ai trouvé assez étrange pour écrire un article sur:

http://ericlippert.com/2011/02/07/strange-but-legal/

12
Eric Lippert

Imaginons que SecondAbstract se trouve au milieu d'une hiérarchie à trois classes et qu'il veuille implémenter des méthodes abstraites à partir de sa base FirstAbstract tout en laissant une autre méthode X implémentée à partir de son enfant ThirdAbstract.

Dans ce cas, SecondAbstract est obligé de décorer la méthode X avec abstract car elle ne veut pas fournir d'implémentation; dans le même temps, il est obligé de le décorer avec override car il ne définit pas une nouvelle méthode X, mais souhaite transférer la responsabilité de la mise en œuvre de X à son enfant. Par conséquent, abstract override.

En général, les concepts modélisés par abstract et override sont orthogonaux. La première force les classes dérivées à implémenter une méthode, tandis que la seconde reconnaît qu'une méthode est identique à celle spécifiée sur une classe de base et non à une variable new.

Donc:

  • ni mot clé: méthode "simple"
  • abstract uniquement: la classe dérivée doit implémenter
  • override uniquement: implémentation de la méthode définie dans la classe de base
  • abstract override: la classe dérivée doit implémenter une méthode définie dans la classe de base
6
Jon

Si vous n'avez pas déclaré SomeMethod en tant que abstract override dans SecondAbstract, le compilateur s'attend à ce que cette classe contienne une implémentation de la méthode. Avec abstract override, il est clair que l'implémentation doit être dans une classe dérivée de SecondAbstract et non dans SecondAbstract.

J'espère que cela t'aides...

0
Francois

Ce modèle de conception est appelé modèle de méthode de modèle.

Page Wikipedia sur les méthodes de modèles

Un exemple simple, non-logiciel: Il existe un groupe d’unités militaires: chars, jets, soldats, cuirassés, etc. Ils doivent tous mettre en œuvre des méthodes communes mais ils les implémenteront très différemment:

  • Bouge toi() 
  • Attaque() 
  • Battre en retraite()
  • Du repos()

etc...

0
noctonura

Cela est fait car dans la classe enfant, vous ne pouvez pas utiliser la méthode abstract avec le même nom que dans la classe de base. override indique au compilateur que vous substituez le comportement de la classe de base.

J'espère que c'est ce que vous recherchez.

0
Amar Palsapure