C # und Java überschreiben Story

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.

Fazit zuerst

  1. Grundsätzlich können nicht alle Methoden ** überschrieben werden **
  2. Verwenden Sie beim Überschreiben die virtuellen und Überschreibungsqualifizierer paarweise
  3. Override ist die "Erweiterung" der Klasse, der neue Modifikator ist das "Hidden" der Klassenmitglieder und das gepaarte Konzept
  1. Grundsätzlich sind alle Methoden ** überschreibbar ** (außer wenn sie als endgültig deklariert sind).
  2. Fügen Sie zum Überschreiben einfach die Annotation Überschreiben hinzu
  3. Kein neuer Modifikator (nur neuer Operator)

Schauen wir uns jeden an.

1. Kann man grundsätzlich überschreiben? unmöglich?

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).

2. Vergleich des Schreibens von Überschreibungen

Für C

Im Prinzip ist das Überschreiben in C # nicht möglich, daher gibt es beim Überschreiben die folgenden Einschränkungen.

  1. Die überschriebene Methode erfordert ** virtuellen Modifikator **
  2. ** Überschreibungsmodifikator ** erforderlich, wenn in einer abgeleiteten Klasse überschrieben wird

Die Notation lautet wie folgt.

class Parent {
    //Überschriebene Methode
    public virtual void Hoge() {...}
}

class Child : Parent { //Eltern erben
    public override void Hoge() {...} //überschreiben
}

Für Java

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() {...}
}

3. Was ist der neue Modifikator?

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.

Zusammenfassung

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.

  1. Verhindern Sie Leistungseinbußen aufgrund von Virtualisierung
  2. Geben Sie explizit überschreibbare Methoden an

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

C # und Java überschreiben Story
[Java] HashCode und gleich Überschreibung
Mit Java verschlüsseln und mit C # entschlüsseln
[Java] Was sind Überschreibungen und Überladungen?
Statische Java-Geschichte
Java-Kern: HotSpot-Compiler und C-Heap
Verknüpfen Sie Java- und C ++ - Code mit SWIG
Java und JavaScript
XXE und Java
Die Richtung von Java in "C ++ Design and Evolution"
Die Geschichte des Java-Initialisierers
Von Java nach C und von C nach Java in Android Studio
Java generische Geschichte
Unterschiede beim Schreiben von Java-, C # - und Javascript-Klassen
Fassen Sie die Unterschiede zwischen C # - und Java-Schrift zusammen
Getter und Setter (Java)
[Java] Thread und ausführbar
Java wahr und falsch
[Java] Vergleich von Zeichenketten und && und ||
Java - Serialisierung und Deserialisierung
[Java] Argumente und Parameter
Lomboks Java 9+ Support-Story
[Java] Verzweigen und Wiederholen
[Java] Variablen- und Typtypen
Java (Klasse und Instanz)
[Java] Überladen und überschreiben
Organisieren Sie Builds in C ++ / Java- und Win / Linux-Kombinationen
Java-Sprache aus der Sicht von Kotlin und C #
Studiere Java # 2 (\ mark and operator)
Java Version 8 und neuere Funktionen
[Java] Aizu Online Judges Geschichte 2
[Java] Aizu Online Judges Geschichte 1
Lösen mit Ruby, Perl und Java AtCoder ABC 113 C Referenz
[Java] Unterschied zwischen == und gleich
[Java] Stapelbereich und statischer Bereich
[Java] Generics-Klasse und Generics-Methode
Java-Programmierung (Variablen und Daten)
Java-Ver- und Entschlüsselung PDF
Schnellstes Primzahl-Beurteilungsprogramm C # Java C ++
Definition und Instanziierung von Java-Klassen
[Java] Über String und StringBuilder
Kotlin Post- und Pre-Inkrement und Operatorüberladung (Vergleich mit C, Java, C ++)
Ruby C Erweiterung und flüchtig
☾ Java / Repeat-Anweisung und Repeat-Steueranweisung
Vor- und Nachteile von Java
Java (bedingte Verzweigung und Wiederholung)
Reproduzieren Sie die Java-Enumeration in C #
Über Java-Paket und Import
Java abstrakte Methoden und Klassen
Java während und für Anweisungen
Java-Kapselung und Getter und Setter
Lösen mit Ruby, Perl und Java AtCoder ABC 129 C (Teil 1)
AtCoder ARC 081 C-Hash, der in Ruby, Perl und Java gelöst werden muss
Informationen zu statischen und nicht statischen Java-Methoden
C # Spickzettel für Java-Techniker
C-, Java-, JDBC-, JSP- und Applet-Tutorials
Ich habe PHP- und Java-Konstruktoren verglichen
Verwenden Sie Java mit MSYS und Cygwin
Verteilte Ablaufverfolgung mit OpenCensus und Java
[Java] Unterschied zwischen Hashmap und HashTable