Es sind drei Schlüsselwörter erforderlich, um dieses Verhalten mit Polymorphismus zu steuern. Virtuell, überschreiben und neu. Diese sind gut erklärt here und von MSDN:
Aufschalten:
Die Überschreibung Modifikator kann auf virtuellen Methoden verwendet werden und muss auf abstrakte Methoden verwendet werden. Dies zeigt an, dass der Compiler die letzte definierte Implementierung einer Methode verwendet. Selbst wenn die Methode für eine Referenz auf die Basisklasse aufgerufen wird, wird sie von der Implementierung überschrieben.
Neu:
Der neue Modifikator weist den Compiler Ihr Kind Klasse Implementierung anstelle der übergeordneten Klasse Implementierung zu verwenden. Jeder Code, der nicht auf Ihre Klasse, sondern auf die Elternklasse verweist, verwendet die Implementierung der Elternklasse.
Ein Beispiel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BindingExample
{
public class SomeBaseClass
{
public virtual string CustomString() => "From SomeBaseClass";
}
public class FirstSpecialisation : SomeBaseClass
{
public override string CustomString() => "From FirstSpecialisation";
}
public class SecondSpecialisation : SomeBaseClass
{
public new string CustomString() => "From SecondSpecialisation";
}
class Program
{
static void Main(string[] args)
{
// Base Example, as expected
SomeBaseClass a1 = new SomeBaseClass();
Console.WriteLine(a1.CustomString());
// First Example, both output the same result
FirstSpecialisation b1 = new FirstSpecialisation();
SomeBaseClass b2 = b1;
Console.WriteLine(b1.CustomString());
Console.WriteLine(b2.CustomString());
// Second Example, output different results
SecondSpecialisation c1 = new SecondSpecialisation();
SomeBaseClass c2 = c1;
Console.WriteLine(c1.CustomString());
Console.WriteLine(c2.CustomString());
Console.ReadLine();
}
}
}
Ausgang:
From SomeBaseClass
From FirstSpecialisation
From FirstSpecialisation
From SecondSpecialisation
From SomeBaseClass
Beachten Sie das obige Verhalten mit der SecondSpecialisation
Klasse auf den Linien 4 und 5
Dies ist besonders interessant in Ihrem Beispiel ist , weil Sie eine Methode mit 2 Tiefen überschreiben. Wenn Sie zweimal überlagern, wird ein ungewöhnliches Verhalten hervorgerufen. Die letzte überschriebene Priorität hat Vorrang. Daher müssen Sie das neue Schlüsselwort verwenden.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BindingExample
{
public class SomeBaseClassA
{
public override string ToString() => "From SomeBaseClassA";
}
public class SpecialisationA : SomeBaseClassA
{
public override string ToString() => "From SpecialisationA";
}
public class SomeBaseClassB
{
public new string ToString() => "From SomeBaseClassB";
}
public class SpecialisationB : SomeBaseClassB
{
public new string ToString() => "From SpecialisationB";
}
class Program
{
static void Main(string[] args)
{
// First Example
SomeBaseClassA a1 = new SomeBaseClassA();
Console.WriteLine(a1);
SpecialisationA a2 = new SpecialisationA();
Console.WriteLine(a2);
SomeBaseClassA a3 = a2;
Console.WriteLine(a3);
// Second Example
SomeBaseClassB b1 = new SomeBaseClassB();
Console.WriteLine(b1.ToString());
SpecialisationB b2 = new SpecialisationB();
Console.WriteLine(b2.ToString());
SomeBaseClassB b3 = b2;
Console.WriteLine(b3.ToString());
Console.ReadLine();
}
}
}
Ausgang:
From SomeBaseClassA
From SpecialisationA
From SpecialisationA
From SomeBaseClassB
From SpecialisationB
From SomeBaseClassB
beobachte ich habe, wenn die ToString
Methode überschrieben, die es auf Object
genannt wurde. Ich nehme an, dies ist, weil die Methode ein Objekt nehmen kann, und weil das neue Schlüsselwort in den 'ToString' Methoden innerhalb der Spezialisierungen verwendet wurde, ruft der Compiler stattdessen Object.ToString
. Dies ist etwas, auf das Sie achten sollten.
Seltsame Welt. Die Leute kennen die komplexe Syntax von Lambda-Ausdrücken, kennen aber die 3. Säule von OOP nicht. –
Seltsame Welt. :) –