Poly = mange
Morf = form
Altså mange
former.
En klasse der
er nedarvet fra en anden kan have form som sig selv eller én klasse den har
nedarvet.
Har man eks.
Defineret en field klasse og nedarvet denne klasse både til et stringfield og
et multivaluefield, så er det muligt at have en liste af fields.
Field er en
abstract base klasse, som der ikke findes en kontret implementering af.
Har man listen
af felter, er det muligt at lave en metode, der hedder GetFieldValue(), denne
returnerer en streng, med værdien af klassen.
Nu er det
muligt at loop over alle felter i listen, og kalde GetFieldValue() på samtlige
fields, der både kan være stringfields og multivaluefields. Ved hjælp af
polymorfi kaldes GetFieldValue() ikke på Field klassen, da denne jo ikke kan
vide hvordan man får feltværdien fra alle slags felter, der i fremtiden kan
kaldes.
Dette kan
ordnes ved at lave metoden i field klassen virtuel, sådan her:
public virtual string GetFieldValue()
{
return string.Empty;
}
Det betyder at metoden
skal behandles virtuelt, hvilket igen betyder at det er 'den mest nedarvede'
metode der kaldes.
Har man altså
et hieraki hvor klassen A er base klassen, herfra nedarves B, og igen C, og D.
På A findes en
virtuel metode Method1(). Denne er defineret i både B og C med override
keywordet.
Kaldes nu en
klasse som følger:
A instansC = new C();
instansC.Method1();
Selvom vi har
en klasse af typen A kaldes nu metoden Method1() på klasse C, da vi egentlig
har en klasse af typen C.
Her behandles
klassen altså som en anden form end den den egentlig har.
På samme måde
kan man kalde på en instans af typen C, kaldes Method1() på denne instans,
kaldes instansen på C, da det er den mest nedarvede metode.
Laver man nu en
metode på klassen D, som hedder Method1() vil man få en advarsel fra
compileren. Man har nu mulighed for at lave metoden som override eller new.
Laves metoden
som override kaldes den virtuelt.
Laves metoden
derimod new, indgår den ikke i det virtuelle nedarvningshieraki.
Dette betyder at
laver man en instans A = new D(); Og
kalder metoden på denne vil man få den fra C, da den er den mest nedarvede i
det virtuelle nedarvnings hieraki. Metoden på D er en helt ny metode og ikke
den som findes på de øvrige klasser
Her er et
eksempel:
public class A
{
public virtual string Method1()
{
return "From class
A";
}
}
public class B : A
{
public override string Method1()
{
return "From class
B";
}
}
public class C: B
{
public override string Method1()
{
return "From class
C";
}
}
public class D : C
{
public new string Method1()
{
return "From class
D";
}
}
class Program
{
static void Main(string[] args)
{
List<A>
listOfAs = new List<A>();
listOfAs.Add(new A());
listOfAs.Add(new B());
listOfAs.Add(new C());
listOfAs.Add(new D());
foreach (A instans in listOfAs)
{
Console.WriteLine(instans.Method1());
}
Console.WriteLine();
A instansOfAA = new A();
A instansOfAB = new B();
A instansOfAC = new C();
A instansOfAD = new D();
C instansOfCD = new D();
D instansOfDD = new D();
Console.WriteLine(instansOfAA.Method1());
Console.WriteLine(instansOfAB.Method1());
Console.WriteLine(instansOfAC.Method1());
Console.WriteLine(instansOfAD.Method1());
Console.WriteLine(instansOfCD.Method1());
Console.WriteLine(instansOfDD.Method1());
}
}
Output fra denne bliver:
From class A
From class B
From class C
From class C
From class A
From class B
From class C
From class C
From class C
From class D
Som det ses
stoppes det virtuelle nedarvningshieraki ved D, da denne erklæres new.
Envidere ses det
at selv om det er ene A’er vi har i listen så kaldes de respektive metoder
virtuelt, og altså på den klasse som de reelt er.
Har du svært ved
at forstå det med polymorfi, så prøv at compilere eksemplerne, og rod lidt med
at lave nye virtuelle funktioner osv.