Par chance, j'ai réexaminé les spécifications de remplacement C # et Java et le comportement du nouveau modificateur spécifique à C # (et C ++), donc je le posterai. Veuillez noter que l'auteur est passé de C # à Java (Android) et écrit du côté Java.
Regardons chacun d'eux.
Il semble que la différence entre C # et Java vient du concept de conception. La citation suivante concerne C ++, mais il semble qu'elle ait été reportée en C #.
En C ++, les fonctions virtuelles ont généralement l'inconvénient d'avoir de moins bonnes performances que les appels de fonction membres réguliers car il n'est pas possible de déterminer quelle fonction membre appeler au moment de la compilation. Par conséquent, les programmeurs C ++ soucieux des performances sont très réticents à ajouter des modificateurs virtuels aux fonctions membres de classe qui n'ont pas besoin d'être héritées. [wiki: Méthode (informatique)](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89_(%E8%) A8% 88% E7% AE% 97% E6% A9% 9F% E7% A7% 91% E5% AD% A6))
pour,
Java est virtuel par défaut [wiki: Méthode (informatique)](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89_(%E8%) A8% 88% E7% AE% 97% E6% A9% 9F% E7% A7% 91% E5% AD% A6))
Donc, toutes les méthodes sont remplaçables par défaut. Notez que «virtuel» fait référence aux membres avec le modificateur virtuel en C #, et indique qu'ils peuvent être remplacés (détails dans la section suivante).
En principe, la substitution n'est pas possible en C #, il existe donc les restrictions suivantes lors de la substitution.
La notation est la suivante.
class Parent {
//Méthode remplacée
public virtual void Hoge() {...}
}
class Child : Parent { //Hériter du parent
public override void Hoge() {...} //passer outre
}
D'un autre côté, Java peut être remplacé en principe, donc ne faites rien à la méthode remplacée et ajoutez l'annotation Override du côté de la classe dérivée pour la remplacer.
class Parent {
//Méthode remplacée
public void hoge() {...}
}
class Child extends Parent { //Hériter du parent
//Remplacer avec l'annotation de remplacement
@Override
public void hoge() {...}
}
Maintenant, avec ce qui précède à l'esprit, jetons un coup d'œil à la référence C #.
new et override ont des significations contradictoires, donc utiliser ces deux modificateurs sur le même membre entraînera une erreur. Le nouveau modificateur crée un nouveau membre avec le même nom et masque le membre d'origine. Le modificateur de remplacement étend l'implémentation des membres hérités. nouveau modificateur (référence C #)
Contrairement au remplacement, le nouveau modificateur masque le membre sous-jacent [^ 1], mais exécutons en fait le programme de console pour le vérifier.
class Program {
static void Main(string[] args) {
Parent parent = new Parent();
Child child = new Child();
Parent childInParent = new Child(); //Le comportement de ce gars change
//production
parent.Hoge(); //Parent#Hoge()
parent.VirtualMethod(); //Parent#VirtualMethod()
child.Hoge(); //Child#Hoge()
child.VirtualMethod(); //Child#VirtualMethod()
childInParent.Hoge(); //Parent#Hoge()← Sorties parents (* 1)
childInParent.VirtualMethod(); //Child#VirtualMethod()
Console.ReadLine();
}
}
public class Parent {
public void Hoge() {
Console.WriteLine("Parent#Hoge()");
}
//Les modificateurs virtuel et de remplacement sont jumelés (* 3)
public virtual void VirtualMethod() {
Console.WriteLine("Parent#VirtualMethod()");
}
}
public class Child : Parent {
//Masquer avec un nouveau modificateur (* 2)
public new void Hoge() {
Console.WriteLine("Child#Hoge()");
}
//Remplacer (* 3)
public override void VirtualMethod() {
Console.WriteLine("Child#VirtualMethod()");
}
}
Toutes les méthodes C # sont des méthodes non virtuelles, donc ** le type de la variable ** détermine la classe de méthode à appeler.
Dans le code ci-dessus, je veux appeler Child # Hoge ()
car la variable childInParent assigne un objet de type Child, mais comme la variable est de type Parent, Parent # Hoge ()
est appelée. C'est parti (* 1).
D'autre part, la variable de type Child child
génère Child # Hoge ()
lors de l'appel de Hoge (). Cela semble évident, mais cela indique que Parent # Hoge () a été ** caché ** par la méthode Child # Hoge () du même nom (* 2).
En outre, lors du remplacement, un qualificateur virtuel est ajouté pour créer une méthode virtuelle et la classe dérivée est implémentée avec le qualificatif de remplacement (* 3).
Depuis que j'ai écrit la conclusion en premier, il n'y a pas de résumé, mais du marais de Java, vous vous demandez peut-être pourquoi il existe une fonction si similaire à un tel remplacement. Je pense que les avantages de C # du point de vue de Java sont les suivants.
S'il y a des erreurs, nous les corrigerons. Je vous serais reconnaissant si vous pouviez me dire les avantages. Merci pour la lecture.
[^ 1]: les propriétés, les membres de champ, etc. peuvent également être virtualisés, mais omis car la méthode semble être la plus utilisée
Recommended Posts