Quelle est la différence entre l' observation et le remplacement d' une méthode en C #?
Réponses
Trop de publicités?Héritage bien...
Supposons que vous ayez ce cours :
Ensuite, lorsque vous appelez cela :
Supposons que vous avez une classe de base et vous utilisez la classe de base dans tout votre code au lieu des classes héritées, et vous utilisez ombre, il retourne les valeurs de que la classe de base retourne au lieu de suivre l’arborescence de la succession du type réel de l’objet.
Espérons que je suis sensé :)
L'observation est effectivement VB le langage de ce que nous appelons la clandestinité en C#.
Souvent se cacher (observation dans VB) et de substitution sont affichés comme dans la réponse par Stormenet.
Une méthode virtuelle est montré pour être remplacée par une sous-classe et les appels à cette méthode, même sur le super-type de classe ou de l'intérieur de code de la super-classe d'appeler le remplacement de la mise en œuvre de la sous-classe.
Ensuite, une méthode concrète qui s'affiche (l'un ne sont pas marqués comme virtuel ou abstrait) étant caché par l'aide de la new
mot-clé lors de la définition d'une méthode identique, signature sur la sous-classe. Dans ce cas, lorsque la méthode est appelée sur le super-type de classe, la mise en œuvre d'origine est utilisé, la nouvelle application est disponible uniquement sur le sous-classe.
Cependant, ce qui est souvent oubliée, c'est qu'il est également possible de masquer une méthode virtuelle.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new void DoStuff() { //new implementation }
}
B b = new B();
A a = b;
b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.
Remarque: dans l'exemple ci-dessus DoStuff devient concret et ne peut pas être surchargée. Cependant, il est également possible d'utiliser les deux virtual
et new
des mots clés.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new virtual void DoStuff() { //new implementation }
}
class C : B
{
public override void DoStuff() { //replacement implementation }
}
C c = new C();
B b = c;
A a = b;
c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.
Notez que malgré toutes les méthodes virtuelles, le remplacer sur le C n'affecte pas la méthode virtuelle sur Un fait de l'utilisation de new
B se cache la mise en œuvre.
Edit: il a été noté dans les commentaires de cette réponse que ci-dessus peuvent être dangereux, ou au moins pas particulièrement utile. Je dirais que oui, il peut être dangereux et serait là si elle a été utile.
En particulier, vous pourriez obtenir dans toutes sortes d'ennuis si vous modifiez également l'accessibilité des modificateurs. Par exemple:-
public class Foo
{
internal Foo() { }
protected virtual string Thing() { return "foo"; }
}
public class Bar : Foo
{
internal new string Thing() { return "bar"; }
}
À un héritier de Bar
, Foo
's la mise en œuvre de la Chose() reste accessible et remplaçable. Toutes les mesures juridiques et explicable selon .NET type de règles néanmoins assez unintuative.
J'ai posté cette réponse à approfondir la compréhension de la façon dont les choses fonctionnent pas comme une suggestion de techniques qui peuvent être utilisées librement.
Je pense que la principale différence réside dans le fait qu’en ce qui concerne l’observation, vous réutilisez essentiellement le nom et vous ignorez simplement l’utilisation de la super-classe. Avec la substitution, vous modifiez l'implémentation, mais pas l'accessibilité et la signature (par exemple, les types de paramètres et le retour). Voir http://www.geekinterview.com/question_details/19331 .
L'observation est un concept VB.NET. En C #, l'observation est appelée masquage. Il cache la méthode de la classe dérivée. Pour ce faire, utilisez le mot clé "new".
Le mot-clé de substitution est utilisé pour fournir une implémentation entièrement nouvelle d'une méthode de classe de base (marquée «Virtual») dans la classe dérivée.
Fondamentalement, si vous avez quelque chose comme ci-dessous,
Class A
{
}
Class B:A
{
}
A a = new B();
Toute méthode d'appel sur l'objet 'a' sera faite sur le type " a " (Ici le type est 'A') Mais si vous mettez en œuvre la même méthode dans la classe B, qui est déjà présent dans Une Classe, le compilateur va vous donner un avertissement à l'utilisation d'un "Nouveau" mot clé. Si vous utilisez le "Nouveau", il disparaîtra. Autre que cela, il n'y a pas de différence entre l'utilisation de "Nouvelles" ou de ne pas l'utiliser dans la classe héritée.
Dans certains cas, vous pouvez avoir besoin d'appeler une méthode de la classe de référence de l'instance particulière détient, à ce moment, au lieu d'appeler une méthode sur le type d'objet. Dans le cas ci-dessus la référence qu'il détient est "B", mais le type est 'Un'. Donc, si vous voulez l'appel de la méthode qui devrait arriver sur "B", puis vous utilisez le Virtuel et la remplacer pour atteindre cet objectif.
Espérons que cela aide...
Daniel Sandeep.