Jede Methode kann überschreibbar sein (= virtual
) oder nicht. Die Entscheidung trifft derjenige, der die Methode definiert:
class Person
{
public String GetPersonType()
{
return "person";
}
public virtual String GetName()
{
return "generic name";
}
}
Jetzt können Sie die überschreibbaren Methoden überschreiben:
class Friend : Person
{
public Friend() : this("generic name") { }
public Friend(String name)
{
this._name = name;
}
public override String GetName()
{
return _name;
}
}
Sie können die GetPersonType
Methode jedoch nicht überschreiben , da sie nicht virtuell ist.
Erstellen wir zwei Instanzen dieser Klassen:
Person person = new Person();
Friend friend = new Friend("Onotole");
Wenn eine nicht virtuelle Methode GetPersonType
von einer Fiend
Instanz aufgerufen wird, heißt sie tatsächlich Person.GetPersonType
:
Console.WriteLine(friend.GetPersonType());
Wenn die virtuelle Methode GetName
von einer Friend
Instanz Friend.GetName
aufgerufen wird, heißt sie:
Console.WriteLine(friend.GetName());
Wenn die virtuelle Methode GetName
von einer Person
Instanz Person.GetName
aufgerufen wird, heißt sie:
Console.WriteLine(person.GetName());
Wenn eine nicht virtuelle Methode aufgerufen wird, wird der Methodenkörper nicht nachgeschlagen - der Compiler kennt bereits die tatsächliche Methode, die aufgerufen werden muss. Während bei virtuellen Methoden der Compiler nicht sicher sein kann, welche aufgerufen werden soll, wird er zur Laufzeit in der Klassenhierarchie von unten nach oben ab dem Instanztyp nachgeschlagen, auf den die Methode aufgerufen wird: denn friend.GetName
er sieht ab Friend
Klasse und aus findet es sofort, für den person.GetName
Unterricht beginnt es Person
und findet es dort.
Manchmal erstellen Sie eine Unterklasse, überschreiben eine virtuelle Methode und möchten keine weiteren Überschreibungen in der Hierarchie - Sie verwenden dies sealed override
(sagen, Sie sind der letzte, der die Methode überschreibt):
class Mike : Friend
{
public sealed override String GetName()
{
return "Mike";
}
}
Aber manchmal beschließt dein Freund Mike, sein Geschlecht und damit seinen Namen in Alice zu ändern :) Du kannst entweder den Originalcode ändern oder stattdessen die Unterklasse Mike:
class Alice : Mike
{
public new String GetName()
{
return "Alice";
}
}
Hier erstellen Sie eine völlig andere Methode mit demselben Namen (jetzt haben Sie zwei). Welche Methode und wann wird aufgerufen? Es hängt davon ab, wie Sie es nennen:
Alice alice = new Alice();
Console.WriteLine(alice.GetName());
Console.WriteLine(((Mike)alice).GetName());
Wenn Sie es aus Alice
der Perspektive anrufen Alice.GetName
, rufen Sie an , wenn Sie aus der Perspektive Mike
anrufen Mike.GetName
. Hier wird keine Laufzeitsuche durchgeführt, da beide Methoden nicht virtuell sind.
Sie können jederzeit new
Methoden erstellen - unabhängig davon, ob die ausgeblendeten Methoden virtuell sind oder nicht.
Dies gilt auch für Eigenschaften und Ereignisse - sie werden darunter als Methoden dargestellt.