Vous vous demandez quelle est la différence entre les éléments suivants:
Cas 1: Classe de base
public void DoIt();
Cas 1: classe héritée
public new void DoIt();
Cas 2: Classe de base
public virtual void DoIt();
Cas 2: classe héritée
public override void DoIt();
Les cas 1 et 2 semblent avoir le même effet sur la base des tests que j'ai effectués. Y a-t-il une différence ou une manière préférée?
c#
inheritance
overriding
new-operator
Shiraz Bhaiji
la source
la source
Réponses:
appellera
Derived.DoIt
si cela remplaceBase.DoIt
.Appellera d'abord
Base.DoIt
, alorsDerived.DoIt
. Ce sont en fait deux méthodes entièrement distinctes qui portent le même nom, plutôt que la méthode dérivée qui remplace la méthode de base.Source: blog Microsoft
la source
This indicates for the compiler to use the last defined implementation of a method
. comment trouver la dernière implémentation définie d'une méthode ??override
une méthode lorsque la classe de base définit la méthode commevirtual
. Le motvirtual
est la classe de base en disant « Hé, quand je l' appelle cette méthode, il aurait pu pratiquement été remplacée par une mise en œuvre dérivée, donc je ne sais pas vraiment à l' avance ce que la mise en œuvre méthode que je vous appelle en fait à l' exécution. Ainsivirtual
signifie est un espace réservé pour une méthode. Cela implique que les méthodes qui ne sont pas marquées commevirtual
ne peuvent pas être remplacées. Mais vous pouvez remplacer toute méthode non virtuelle dans une classe dérivée avec le modificateurnew
, accessible uniquement au niveau dérivé.virtuel : indique qu'une méthode peut être remplacée par un héritier
override : remplace la fonctionnalité d'une méthode virtuelle dans une classe de base, fournissant des fonctionnalités différentes.
nouveau : cache la méthode d'origine (qui n'a pas besoin d'être virtuelle), offrant des fonctionnalités différentes. Cela ne doit être utilisé que lorsque cela est absolument nécessaire.
Lorsque vous masquez une méthode, vous pouvez toujours accéder à la méthode d'origine en effectuant une conversion vers la classe de base. Ceci est utile dans certains scénarios, mais dangereux.
la source
override
et / ounew
sansvirtual
sur la méthode parent?Dans le premier cas, vous cachez la définition dans la classe parente. Cela signifie qu'il ne sera invoqué que lorsque vous traitez l'objet en tant que classe enfant. Si vous convertissez la classe en son type parent, la méthode du parent sera invoquée. Dans la deuxième instance, la méthode est remplacée et sera invoquée, que l'objet soit converti en classe enfant ou parent.
la source
essayez de suivre: (case1)
Edit: virtual + override sont résolus lors de l'exécution (donc override remplace vraiment les méthodes virtuelles), tandis que new crée simplement une nouvelle méthode avec le même nom et cache l'ancienne, elle est résolue au moment de la compilation -> votre compilateur appellera la méthode il ' voit '
la source
Dans le cas 1, si vous utilisez la méthode DoIt () de la classe héritée alors que le type est déclaré comme classe de base, vous verrez même l'action de la classe de base.
la source
La différence entre les deux cas est que dans le cas 1, la
DoIt
méthode de base n'est pas remplacée, juste masquée. Cela signifie que selon le type de variable dépend de la méthode qui sera appelée. Par exemple:Cela peut être très déroutant et entraîner des comportements non attendus et doit être évité si possible. Ainsi, le moyen préféré serait le cas 2.
la source
Ma façon de garder à l'esprit les deux mots clés qu'ils sont opposés l'un à l'autre.
override
: levirtual
mot clé doit être défini pour remplacer la méthode. La méthode utilisant unoverride
mot clé qui, quel que soit le type de référence (référence de la classe de base ou classe dérivée), si elle est instanciée avec la classe de base, la méthode de la classe de base s'exécute. Sinon, la méthode des classes dérivées s'exécute.new
: si le mot-clé est utilisé par une méthode, contrairement auoverride
mot-clé, le type de référence est important. S'il est instancié avec une classe dérivée et que le type de référence est la classe de base, la méthode de la classe de base s'exécute. S'il est instancié avec une classe dérivée et que le type de référence est une classe dérivée, la méthode de la classe dérivée s'exécute. À savoir, c'est le contraste duoverride
mot - clé. En passant, si vous oubliez ou omettez d'ajouter un nouveau mot clé à la méthode, le compilateur se comporte par défaut lorsque lenew
mot clé est utilisé.Appelez en principal:
Production:
Nouvel exemple de code,
Jouez avec le code en commentant un par un.
la source
Si le mot clé
override
est utilisé dans la classe dérivée, il remplace la méthode parent.Si le mot
new
- clé est utilisé dans la classe dérivée, dérivez la méthode masquée par la méthode parent.la source
J'avais la même question et c'est vraiment déroutant, vous devriez considérer que le remplacement et les nouveaux mots clés ne fonctionnent qu'avec des objets de type classe de base et de valeur de classe dérivée. Dans ce cas seulement, vous verrez l'effet du remplacement et du nouveau: Donc, si vous avez
class A
etB
,B
hérite deA
, vous instanciez un objet comme celui-ci:Désormais, les méthodes d'appel prendront en compte son état. Override : signifie qu'il étend la fonction de la méthode, puis il utilise la méthode dans la classe dérivée, tandis que new indique au compilateur de masquer la méthode dans la classe dérivée et d'utiliser la méthode dans la classe de base à la place. Voici une très bonne vue de ce sujet:
https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396
la source
L'article ci-dessous est dans vb.net mais je pense que l'explication sur les nouveaux remplacements vs est très facile à comprendre.
https://www.codeproject.com/articles/17477/the-dark-shadow-of-overrides
À un moment donné de l'article, il y a cette phrase:
La réponse acceptée à cette question est parfaite, mais je pense que cet article fournit de bons exemples pour ajouter un meilleur sens aux différences entre ces deux mots clés.
la source
De tous ceux-là, le nouveau est le plus déroutant. Grâce à l'expérimentation, le nouveau mot-clé revient à donner aux développeurs la possibilité de remplacer l'implémentation de classe héritée par l'implémentation de classe de base en définissant explicitement le type. C'est comme penser l'inverse.
Dans l'exemple ci-dessous, le résultat renverra "Résultat dérivé" jusqu'à ce que le type soit explicitement défini comme test BaseClass, alors seulement "Résultat de base" sera renvoyé.
la source
La différence fonctionnelle ne sera pas montrée dans ces tests:
Dans cet exemple, le Doit qui est appelé est celui auquel vous vous attendez.
Pour voir la différence, vous devez procéder comme suit:
Vous verrez si vous exécutez ce test que dans le cas 1 (tel que vous l'avez défini), l'
DoIt()
entréeBaseClass
est appelée, dans le cas 2 (telle que vous l'avez définie), l'DoIt()
entréeDerivedClass
est appelée.la source
Dans le premier cas, il appellera la méthode dérivée de classe DoIt () parce que le nouveau mot-clé masque la méthode de classe de base DoIt ().
Dans le deuxième cas, il appellera overriden DoIt ()
laissez créer une instance de ces classes
Tout est attendu ci-dessus. Laissez la valeur instanceB et instanceC à instanceA et appelez la méthode DoIt () et vérifiez le résultat.
la source
Toutes les combinaisons de none, virtual, override, new et abstract:
la source