Was ist der Unterschied zwischen dem Überschreiben und neuen Schlüsselwörtern in C #?

75

Was ist der Unterschied zwischen den Schlüsselwörtern overrideund newin C # beim Definieren von Methoden in Klassenhierarchien?

Jaywayco
quelle

Antworten:

101

Die folgende Seite fasst Ihre Frage sehr gut zusammen.

Wissen, wann Override und neue Schlüsselwörter verwendet werden müssen

Zusammenfassung

Überschreiben : Wenn eine Methode einer Basisklasse in einer abgeleiteten Klasse überschrieben wird, wird die Version in der abgeleiteten Klasse verwendet, auch wenn der aufrufende Code nicht "wusste", dass das Objekt eine Instanz der abgeleiteten Klasse war.

Neu : Wenn Sie das neue Schlüsselwort anstelle des Überschreibens verwenden, überschreibt die Methode in der abgeleiteten Klasse die Methode in der Basisklasse nicht, sondern verbirgt sie lediglich.

Wenn Sie weder neu noch Überschreibungen angeben, ist die resultierende Ausgabe dieselbe wie bei Angabe von neu, es wird jedoch auch eine Compiler-Warnung angezeigt (da Sie möglicherweise nicht wissen, dass Sie eine Methode in der Basisklasse ausblenden Methode, oder Sie wollten sie möglicherweise überschreiben und haben lediglich vergessen, das Schlüsselwort anzugeben.

Override : Wird mit der Methode virtual / abstract / override in der Basisklasse verwendet

Neu : Wenn die Basisklasse die Methode nicht als virtuell / abstrakt / überschrieben deklariert hat

Brian Graham
quelle
9
Können Sie bitte auch hier die wichtigsten Informationen angeben? Es hilft, die Informationen hier zu behalten und schützt vor Linkfäule (unwahrscheinlich bei einem MSDN-Blog, aber Sie wissen es nie).
ChrisF
3
lol "unwahrscheinlich" Ich erhalte eine Weiterleitung, gefolgt von "Zugriff verweigert Sie haben keine Berechtigung, diesen Artikel anzuzeigen / herunterzuladen."
Tobsen
78

newschattiert die Methode mit einer völlig neuen Methode (die möglicherweise dieselbe Signatur hat oder nicht), anstatt sie zu überschreiben (in diesem Fall muss die neue Methode dieselbe Signatur haben), was bedeutet, dass Polymorphismus nicht funktioniert. Zum Beispiel haben Sie diese Klassen:

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}

Wenn du das tust:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3

Da Sie mit neue Methodensignaturen definieren können, kann newder Compiler nicht wissen, dass die Instanz von Atatsächlich eine Instanz von ist Bund die neuen Methodendefinitionen Bverfügbar sein sollten. newkann verwendet werden, wenn die Methode, Eigenschaft, das Feld oder das Ereignis des übergeordneten Objekts nicht mit deklariert virtualist und virtualdie geerbte Methode aufgrund des Fehlens des Compilers nicht "nachgeschlagen" wird. Mit virtualund overridefunktioniert es jedoch.

Ich würde Ihnen dringend empfehlen, dies zu vermeiden new. Im besten Fall ist es verwirrend, weil Sie eine Methode mit einem Namen definieren, der als etwas anderes erkannt werden könnte. Im schlimmsten Fall kann sie Fehler verbergen, scheinbar unmögliche Fehler verursachen und die Erweiterung der Funktionalität erschweren.

Ry-
quelle
14
Dies sollte die akzeptierte Antwort sein. Anhand von Beispielen werden die Unterschiede und die Auswirkungen erläutert. Die akzeptierte Antwort ist ziemlich vage.
Theyetiman
Ähnliches passiert bei Verwendung einer Schnittstelle (wie in B A erweitert, A Schnittstelle implementiert mit Hello(), B Variable mit Schnittstellentyp zuweisen). Es wäre gut, dies auch in Ihrer Antwort zu verdeutlichen, da dies die Situation war, nach der ich gesucht habe.
Ahong
9

Sieht aus wie eine alte Frage, lassen Sie mich eine andere Antwort versuchen:

  1. new : Wie der Name schon sagt, handelt es sich um ein neues Mitglied in der Familie der Vererbungshierarchien, das als Basismitglied weiter unten in der Kette verwendet wird (sofern es als virtuell markiert ist).

  2. override : Das bedeutet, dass ich die Implementierung der Mitglieder meiner Elternklasse nicht akzeptiere und es anders machen werde.

Dhananjay
quelle
3

Betrachten Sie die folgende Klassenhierarchie:

using System;

namespace ConsoleApp
{     
     public static class Program
     {   
          public static void Main(string[] args)
          {    
               Overrider overrider = new Overrider();
               Base base1 = overrider;
               overrider.Foo();
               base1.Foo();

               Hider hider = new Hider();
               Base base2 = hider;
               hider.Foo();
               base2.Foo();
          }   
     }   

     public class Base
     {
         public virtual void Foo()
         {
             Console.WriteLine("Base      => Foo");
         }
     }

     public class Overrider : Base
     {
         public override void Foo()
         {
             Console.WriteLine("Overrider => Foo");
         }
     }

     public class Hider : Base
     {
         public new void Foo()
         {
             Console.WriteLine("Hider     => Foo");
         }
     }
}    

Die Ausgabe der obigen Codes muss sein:

Overrider => Foo
Overrider => Foo

Hider     => Foo
Base      => Foo
  • Eine Unterklasse overrideseiner virtuellen Methode durch Anwenden von override modifier:
  • Wenn Sie hideabsichtlich Mitglied werden möchten , können Sie in diesem Fall das new modifierauf das Mitglied in der Unterklasse anwenden .The new modifier does nothing more than suppress the compiler warning that would otherwise result
Sina Lotfi
quelle
Ein gutes Beispiel, ich denke, es wäre besser lesbar, wenn Sie die ProgramKlasse und andere Klassen in zwei separate Codeblöcke aufteilen , wobei die Ausgabe dem Methodenaufruf als Kommentar entspricht, z base2.Foo(); // Base => Foo. Ich würde auch den Namespace weglassen
ahong
1

overrideMit dieser Option können Sie eine virtuelle Methode in einer Basisklasse überschreiben, sodass Sie eine andere Implementierung einfügen können. newDadurch wird eine nicht virtuelle Methode in einer Basisklasse ausgeblendet.

Daniel Mann
quelle
So viel wusste ich jedoch, dass Override eine Basisklassenmethode effektiv verbergen wird
Jaywayco
2
Keine Überschreibung verbirgt die Basisklassenmethode nicht. Beim Überschreiben werden Aufrufe der Basisklassenmethode in Aufrufe der abgeleiteten Klassenmethode umgewandelt. In gewisser Weise ist die Methode in der abgeleiteten Klasse dieselbe wie die in der Basisklasse. Während newes sich um eine völlig unabhängige Methode handelt, die zufällig denselben Namen hat.
CodesInChaos
@ CodeInChaos Danke, dass Sie gesagt haben, was ich besser sagen wollte, als ich es sagen konnte :)
Daniel Mann