2008-12-25 19 views

Antwort

128

Well Erbe ...

nehme an, Sie diese Klassen haben:

class A { 
    public int Foo(){ return 5;} 
    public virtual int Bar(){return 5;} 
} 
class B : A{ 
    public new int Foo() { return 1;}  //shadow 
    public override int Bar() {return 1;} //override 
} 

dann, wenn Sie dies nennen:

A clA = new A(); 
B clB = new B(); 

Console.WriteLine(clA.Foo()); // output 5 
Console.WriteLine(clA.Bar()); // output 5 
Console.WriteLine(clB.Foo()); // output 1 
Console.WriteLine(clB.Bar()); // output 1 

//now let's cast B to an A class 
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow 
Console.WriteLine(((A)clB).Bar()); // output 1 

Angenommen, Sie eine Basisklasse haben und Sie die Basis Klasse in Ihrem gesamten Code anstelle der geerbten Klassen, und Sie verwenden Schatten, es wird die Werte zurückgeben, die die Basisklasse zurückgibt, anstatt dem Vererbungsbaum des realen Typs des Objekts zu folgen.

Run code here

Hoffnung Ich mache Sinn :)

+11

Das Überschreiben bietet Polymorphismus, Shadowing bietet eine andere Implementierung auf dieser Ebene der Hierarchie, aber nicht polymorph. –

+0

@ribeas, Welche Definition von Polymorphismus würden Sie verwenden, um diese Schlussfolgerung zu ziehen? – AnthonyWJones

+8

@AnthonyWJones, Polymorphismus ist die Fähigkeit eines (abgeleiteten) Typs, als ein anderer (Basis-) Typ verwendet zu werden, wobei die tatsächliche Implementierung (Verhalten) die des realen spezifischen (abgeleiteten) Typs ist. Wenn Sie überschreiben, wird abgeleitete Methode durch Verweis auf Basis aufgerufen, aber wenn Sie Schatten, der nicht wahr ist –

6

Ich denke, der Hauptunterschied besteht darin, dass Sie mit Shadowing im Wesentlichen den Namen wiederverwenden und nur die Oberklasse ignorieren. Beim Überschreiben ändern Sie die Implementierung, nicht jedoch die Erreichbarkeit und die Signatur (z. B. Parametertypen und Rückgabe). Siehe http://www.geekinterview.com/question_details/19331.

31

Shadowing ist eigentlich VB parlance für das, was wir als Versteck in C# beziehen würde.

Häufig werden Verbergen (Beschattung in VB) und Übersteuern wie in der Antwort von Stormenet gezeigt.

Es wird gezeigt, dass eine virtuelle Methode von einer Unterklasse überschrieben wird und Aufrufe an diese Methode selbst für den Superklasse-Typ oder aus dem Inside-Code der Superklasse die Ersatzimplementierung von der Unterklasse aufrufen.

Dann wird eine konkrete Methode angezeigt (eine nicht als virtuell oder abstrakt markiert), die durch das Schlüsselwort new beim Definieren einer Methode mit identischer Signatur in der Unterklasse ausgeblendet wird. In diesem Fall, wenn die Methode für den Super-Class-Typ aufgerufen wird, wird die ursprüngliche Implementierung verwendet, die neue Implementierung ist nur für die Unterklasse verfügbar.

Was jedoch oft übersehen wird ist, dass es auch möglich ist, eine virtuelle Methode zu verstecken.

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. 

Hinweis im obigen Beispiel wird DoStuff konkretisiert und kann nicht überschrieben werden. Es ist jedoch auch möglich, die Schlüsselwörter virtual und new zusammen zu verwenden.

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. 

Beachten Sie, dass trotz aller Methoden sind virtuelle beteiligt, die Überschreibung auf C, um die virtuelle Methode auf A nicht beeinflusst wegen der Verwendung von new in B verbirgt die A-Implementierung.

Bearbeiten: Es wurde in den Kommentaren zu dieser Antwort festgestellt, dass die oben genannten möglicherweise gefährlich oder zumindest nicht besonders nützlich sind. Ich würde sagen, ja, es kann gefährlich sein und wäre da draußen, wenn es überhaupt nützlich wäre.

Insbesondere könnten Sie in alle möglichen Schwierigkeiten geraten, wenn Sie auch die Accessability Modifier ändern.Zum Beispiel: -

public class Foo 
{ 
    internal Foo() { } 
    protected virtual string Thing() { return "foo"; } 
} 

public class Bar : Foo 
{ 
internal new string Thing() { return "bar"; } 
} 

Um einen externen inheritor von Bar, Foo ‚s Implementierung von Thing() bleibt zugänglich und überschreibbar. Alle legalen und erklärbar nach .NET-Regeln sind nie völlig unintuativ.

Ich habe diese Antwort geschrieben, um ein Verständnis dafür zu vertiefen, wie Dinge nicht als ein Vorschlag von Techniken arbeiten, die frei verwendet werden können.

+2

Gut zu wissen, dass. Trotzdem kann es gefährlich sein :) – Stormenet

+2

Alle Werkzeuge können gefährlich sein, wenn sie nicht richtig benutzt werden. – AnthonyWJones

+1

Aber es ist Usability scheint wirklich fraglich! Gibt es eine "seriöse" Open-Source-App, die dies nutzt? – Jox

0

Grundsätzlich, wenn Sie so etwas wie unten haben,

Class A 
{ 
} 

Class B:A 
{ 
} 

A a = new B(); 

Jede Methode, die Sie für das Objekt aufrufen ‚a‘ wird von der Art von ‚a‘ gemacht werden (Hier ist der Typ ‚A‘) Aber Wenn Sie die gleiche Methode in Klasse B implementieren, die bereits in Klasse A vorhanden ist, gibt Ihnen der Compiler eine Warnung, ein Schlüsselwort "New" zu verwenden. Wenn Sie "Neu" verwenden, wird die Warnung ausgeblendet. Ansonsten gibt es keinen Unterschied zwischen der Verwendung von "Neu" oder der Nichtverwendung in der geerbten Klasse.

In einigen Situationen müssen Sie möglicherweise eine Methode der Referenzklasse aufrufen, die die bestimmte Instanz zu diesem Zeitpunkt enthält, anstatt eine Methode für den Objekttyp aufzurufen. Im obigen Fall ist der Verweis "B", aber der Typ ist "A". Wenn Sie möchten, dass der Methodenaufruf auf "B" erfolgt, verwenden Sie Virtual und Override, um dies zu erreichen.

Hoffe, dies hilft ...

Daniel Sandeep.

3

Shadowing ist ein VB.NET-Konzept. In C# ist Shadowing als Verstecken bekannt. Es verbirgt die abgeleitete Klassenmethode. Dies wird mit dem Schlüsselwort 'new' erreicht.

Das Schlüsselwort Override wird verwendet, um eine vollständig neue Implementierung einer Basisklassenmethode (die mit "Virtual" gekennzeichnet ist) in der abgeleiteten Klasse bereitzustellen.