Durch Zufall habe ich die C # - und Java-Überschreibungsspezifikationen und das Verhalten des neuen Modifikators, der für C # (und C ++) spezifisch ist, erneut überprüft, sodass ich ihn veröffentlichen werde. Bitte beachten Sie, dass der Autor von C # zu Java (Android) gewechselt ist und von der Java-Seite schreibt.
Schauen wir uns jeden an.
Es scheint, dass der Unterschied zwischen C # und Java vom Designkonzept herrührt. Das nächste Zitat handelt von C ++, aber es scheint, dass es auf C # übertragen wurde.
In C ++ haben virtuelle Funktionen im Allgemeinen den Nachteil einer schlechteren Leistung als normale Aufrufe von Elementfunktionen, da nicht ermittelt werden kann, welche Elementfunktion zur Kompilierungszeit aufgerufen werden soll. Aus diesem Grund zögern leistungsbewusste C ++ - Programmierer sehr, den Funktionen von Klassenmitgliedern, die nicht vererbt werden müssen, virtuelle Modifikatoren hinzuzufügen. [Wiki: Methode (Informatik)](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))
zum,
Java ist standardmäßig virtuell [Wiki: Methode (Informatik)](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))
Daher sind alle Methoden standardmäßig überschreibbar. Beachten Sie, dass "virtuell" sich auf Mitglieder mit dem virtuellen Modifikator in C # bezieht und angibt, dass sie überschrieben werden können (Details im nächsten Abschnitt).
Im Prinzip ist das Überschreiben in C # nicht möglich, daher gibt es beim Überschreiben die folgenden Einschränkungen.
Die Notation lautet wie folgt.
class Parent {
//Überschriebene Methode
public virtual void Hoge() {...}
}
class Child : Parent { //Eltern erben
public override void Hoge() {...} //überschreiben
}
Auf der anderen Seite kann Java im Prinzip überschrieben werden. Tun Sie also nichts mit der überschriebenen Methode und fügen Sie die Annotation Override auf der Seite der abgeleiteten Klasse hinzu, um sie zu überschreiben.
class Parent {
//Überschriebene Methode
public void hoge() {...}
}
class Child extends Parent { //Eltern erben
//Überschreiben mit Annotation überschreiben
@Override
public void hoge() {...}
}
Schauen wir uns nun vor diesem Hintergrund die C # -Referenz an.
new und override haben widersprüchliche Bedeutungen. Die Verwendung dieser beiden Modifikatoren für dasselbe Element führt daher zu einem Fehler. Der neue Modifikator erstellt ein neues Mitglied mit demselben Namen und verbirgt das ursprüngliche Mitglied. Der Überschreibungsmodifikator erweitert die Implementierung geerbter Mitglieder. neuer Modifikator (C # -Referenz)
Im Gegensatz zur Überschreibung verbirgt der neue Modifikator das zugrunde liegende Element [^ 1], aber lassen Sie uns das Konsolenprogramm tatsächlich ausführen, um es zu überprüfen.
class Program {
static void Main(string[] args) {
Parent parent = new Parent();
Child child = new Child();
Parent childInParent = new Child(); //Das Verhalten dieses Mannes ändert sich
//Ausgabe
parent.Hoge(); //Parent#Hoge()
parent.VirtualMethod(); //Parent#VirtualMethod()
child.Hoge(); //Child#Hoge()
child.VirtualMethod(); //Child#VirtualMethod()
childInParent.Hoge(); //Parent#Hoge()← Übergeordnete Ausgänge (* 1)
childInParent.VirtualMethod(); //Child#VirtualMethod()
Console.ReadLine();
}
}
public class Parent {
public void Hoge() {
Console.WriteLine("Parent#Hoge()");
}
//Die Modifikatoren virtuell und überschreiben sind gepaart (* 3)
public virtual void VirtualMethod() {
Console.WriteLine("Parent#VirtualMethod()");
}
}
public class Child : Parent {
//Mit neuem Modifikator ausblenden (* 2)
public new void Hoge() {
Console.WriteLine("Child#Hoge()");
}
//Überschreiben (* 3)
public override void VirtualMethod() {
Console.WriteLine("Child#VirtualMethod()");
}
}
Alle C # -Methoden sind nicht virtuelle Methoden, daher bestimmt ** der Variablentyp , welche Methodenklasse aufgerufen werden soll. Im obigen Code möchte ich "Child # Hoge ()" aufrufen, weil die Variable childInParent ein Objekt vom Typ Child zuweist, aber weil die Variable vom Typ Parent ist, wird "Parent # Hoge ()" aufgerufen. Es ist weg ( 1).
Andererseits gibt die Child-Typvariable child
beim Aufrufen von Hoge () Child # Hoge ()
aus. Es scheint offensichtlich, aber dies zeigt an, dass Parent # Hoge () durch die gleichnamige Methode Child # Hoge () (* 2) ** ausgeblendet ** wurde.
Außerdem wird beim Überschreiben ein virtuelles Qualifikationsmerkmal hinzugefügt, um es zu einer virtuellen Methode zu machen, und es wird mit einem Überschreibungsqualifikationsmerkmal in der abgeleiteten Klasse (* 3) implementiert.
Da ich die Schlussfolgerung zuerst geschrieben habe, gibt es keine Zusammenfassung, aber aus dem Java-Sumpf fragen Sie sich vielleicht, warum es eine Funktion gibt, die einer solchen Überschreibung so ähnlich ist. Ich denke, die Vorteile von C # aus der Sicht von Java sind wie folgt.
Wenn es Fehler gibt, werden wir sie korrigieren. Ich wäre Ihnen dankbar, wenn Sie mir die Vorteile erläutern könnten. Danke fürs Lesen.
[^ 1]: Eigenschaften, Feldelemente usw. können ebenfalls virtualisiert, jedoch weggelassen werden, da die Methode am häufigsten verwendet wird
Recommended Posts