Quelles sont les différences entre déclarer une méthode dans un type de base " virtual
" et la remplacer ensuite dans un type enfant à l'aide du override
mot clé " " par opposition à simplement utiliser le new
mot clé " " lors de la déclaration de la méthode correspondante dans le type enfant?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
la source
la source
new
crée un nouveau membre avec le même nom et provoque la dissimulation du membre d'origine, tout enoverride
Réponses:
Le mot-clé "new" ne remplace pas, il signifie une nouvelle méthode qui n'a rien à voir avec la méthode de classe de base.
Ceci est faux, si vous avez utilisé la substitution, cela aurait été imprimé vrai.
(Code de base tiré de Joseph Daigle)
Donc, si vous faites du vrai polymorphisme, VOUS DEVEZ TOUJOURS SUPPRIMER . Le seul endroit où vous devez utiliser "nouveau" est lorsque la méthode n'est liée en aucune façon à la version de la classe de base.
la source
virtual
de base etoverride
de dérivé? Pourquoi existe-t-il? Le code fonctionnera toujours même sansnew
- est-ce donc simplement de la lisibilité?Je trouve toujours des choses comme ça plus faciles à comprendre avec des images:
Encore une fois, en prenant le code de Joseph Daigle,
Si vous appelez ensuite le code comme ceci:
REMARQUE: L'important est que notre objet est en fait un
Bar
, mais nous le stockons dans une variable de typeFoo
(c'est similaire à le transtyper)Le résultat sera alors le suivant, selon que vous avez utilisé
virtual
/override
ounew
lors de la déclaration de vos classes.la source
Voici du code pour comprendre la différence de comportement des méthodes virtuelles et non virtuelles:
la source
new
pour "cacher" la méthode de base, alors que tout simplement ne pas utiliser le remplacement semble faire la même chose?virtual
et le compilateur se plaindra s'il voit le même nom de fonction sur une classe "bloodline" sansvirtual
signatureLe
new
mot clé crée en fait un membre complètement nouveau qui n'existe que sur ce type spécifique.Par exemple
La méthode existe sur les deux types. Lorsque vous utilisez la réflexion et obtenez les membres de type
Bar
, vous trouverez en fait 2 méthodes appeléesDoSomething()
qui se ressemblent exactement. En utilisant,new
vous masquez efficacement l'implémentation dans la classe de base, de sorte que lorsque les classes dérivent deBar
(dans mon exemple) l'appel de méthode àbase.DoSomething()
va àBar
et nonFoo
.la source
virtual / override indique au compilateur que les deux méthodes sont liées et que dans certaines circonstances, lorsque vous pensez que vous appelez la première méthode (virtuelle), il est en fait correct d'appeler la deuxième méthode (remplacée) à la place. C'est le fondement du polymorphisme.
Appellera la méthode VirtualFoo () remplacée de la sous-classe.
new indique au compilateur que vous ajoutez une méthode à une classe dérivée portant le même nom qu'une méthode de la classe de base, mais qu'elles n'ont aucune relation les unes avec les autres.
Appellera la méthode NewBar () de BaseClass, alors que:
Appellera la méthode NewBar () de la sous-classe.
la source
Au-delà des détails techniques, je pense que l'utilisation de virtual / override communique beaucoup d'informations sémantiques sur la conception. Lorsque vous déclarez une méthode virtuelle, vous indiquez que vous vous attendez à ce que les classes d'implémentation veuillent fournir leurs propres implémentations non par défaut. L'omission de cela dans une classe de base, de même, déclare l'attente que la méthode par défaut devrait suffire pour toutes les classes d'implémentation. De même, on peut utiliser des déclarations abstraites pour forcer les classes d'implémentation à fournir leur propre implémentation. Encore une fois, je pense que cela communique beaucoup sur la façon dont le programmeur s'attend à ce que le code soit utilisé. Si j'écrivais à la fois les classes de base et d'implémentation et que je me retrouvais à utiliser de nouvelles, je repenserais sérieusement la décision de ne pas rendre la méthode virtuelle dans le parent et de déclarer mon intention spécifiquement.
la source
La différence entre le mot clé de remplacement et le nouveau mot clé est que le premier remplace la méthode et le dernier masque la méthode.
Consultez les liens suivants pour plus d'informations ...
MSDN et autres
la source
new
le mot clé est pour cacher. - signifie que vous cachez votre méthode lors de l'exécution. La sortie sera basée sur la méthode de classe de base.override
pour passer outre. - signifie que vous invoquez votre méthode de classe dérivée avec la référence de la classe de base. La sortie sera basée sur la méthode de classe dérivée.la source
Ma version d'explication vient de l'utilisation des propriétés pour aider à comprendre les différences.
override
est assez simple, non? Le type sous-jacent remplace celui du parent.new
est peut-être trompeur (pour moi c'était le cas). Les propriétés sont plus faciles à comprendre:En utilisant un débogueur, vous pouvez remarquer qu'il
Foo foo
a 2GetSomething
propriétés, car il a en fait 2 versions de la propriété,Foo
's etBar
', et pour savoir laquelle utiliser, c # "choisit" la propriété pour le type actuel.Si vous vouliez utiliser la version de la barre, vous auriez utilisé la substitution ou utiliser à la
Foo foo
place.Bar bar
a seulement 1 , car il veut un comportement complètement nouveau pourGetSomething
.la source
Ne pas marquer une méthode avec quoi que ce soit signifie: Lier cette méthode en utilisant le type de compilation de l'objet, pas le type d'exécution (liaison statique).
Marquer une méthode avec des
virtual
moyens: Liez cette méthode en utilisant le type d'exécution de l'objet, et non le type de temps de compilation (liaison dynamique).Marquer une
virtual
méthode de classe de base avecoverride
dans une classe dérivée signifie: Il s'agit de la méthode à lier à l'aide du type d'exécution de l'objet (liaison dynamique).Marquer une
virtual
méthode de classe de base avecnew
dans une classe dérivée signifie: Il s'agit d'une nouvelle méthode, qui n'a aucun rapport avec celle portant le même nom dans la classe de base et qui doit être liée à l'aide du type de temps de compilation de l'objet (liaison statique).Ne pas marquer une
virtual
méthode de classe de base dans la classe dérivée signifie: Cette méthode est marquée commenew
(liaison statique).Marquer une méthode
abstract
signifie: Cette méthode est virtuelle, mais je ne déclarerai pas de corps pour elle et sa classe est également abstraite (liaison dynamique).la source