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 GetPersonTypeMethode 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 GetPersonTypevon einer FiendInstanz aufgerufen wird, heißt sie tatsächlich Person.GetPersonType:
Console.WriteLine(friend.GetPersonType());
Wenn die virtuelle Methode GetNamevon einer FriendInstanz Friend.GetNameaufgerufen wird, heißt sie:
Console.WriteLine(friend.GetName());
Wenn die virtuelle Methode GetNamevon einer PersonInstanz Person.GetNameaufgerufen 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.GetNameer sieht ab FriendKlasse und aus findet es sofort, für den person.GetNameUnterricht beginnt es Personund 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 Aliceder Perspektive anrufen Alice.GetName, rufen Sie an , wenn Sie aus der Perspektive Mikeanrufen Mike.GetName. Hier wird keine Laufzeitsuche durchgeführt, da beide Methoden nicht virtuell sind.
Sie können jederzeit newMethoden 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.