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.
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.
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.
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:
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:
abstract
uniquement: la classe dérivée doit implémenteroverride
uniquement: implémentation de la méthode définie dans la classe de baseabstract override
: la classe dérivée doit implémenter une méthode définie dans la classe de baseSi 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...
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:
etc...
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.