Overriding in C#
Inleiding
In de post over overerving hebben we laten zien hoe we gebruik kunnen maken van een bestaande klasse en hoe we alles van die klasse (de parent class) kunnen gebruiken. Op die manier “erf” je de zaken van een parent zodat je die functionaliteit niet nogmaals in de child class hoeft in te bouwen.
De functionaliteit van de parent klass hoeft niet altijd een in beton gegoten waarheid te zijn en we kunnen een eigen draai geven aan de functionaliteiten van de parent class. Zo hebben alle vogels standaard een snavel en als je wilt afwijken van die standaard functionaliteit dan kun je de standaard functionaliteit “overriden” zodat dat arme beest opeens geen snavel meer heeft, maar de kop van een tijger zoals in de uitgelichte afbeelding.
We lichten het één en ander weer toe aan de hand van drie autofabrikanten die elkaar het leven zuur maken. Deze post gaat verder met het voorbeeld dat in de post over overerving is besproken. Het verdient de aanbeveling eerst de desbetreffende post te lezen alvorens verder te gaan met deze post.
Overriding
Autofabrikant MGIM (Migraine Imperialist Motors Corporation Groupe) weet de hand te leggen op een assembly van haar aartsrivaal GHB (GuanggongHunnenburgBetrieb) en ze besluit de geassimileerde (gestolen) technologie hier en daar wat aan te passen. De assembly heeft een methode OverjeAuto() en die methode heeft de key word virtual.
// Methode OverjeAuto
public virtual string OverJeAuto(int kleur) { ... }
Concurrent GHB heeft nagelaten de virtual key word weg te halen en dat geeft MGIM de mogelijkheid om de methode te overriden en een eigen draai te geven aan die methode.
Milieuaspecten worden door MGIM beschouwd als vervelende bijkomstigheden die alleen maar de winsten voor de aandeelhouders drukken. MGIM besluit de methode dan ook zodanig aan te passen dat ongeacht de kleur van de milieusticker altijd een lovende tekst wordt getoond m.b.t. de vervuilingsgraad:
public override string OverJeAuto(int kleur) {
// niet moeilijk doen met de kleur
// van de milieusticker, altijd dit doen:
return
"- We care for the environment and so does your car.";
}
met dit als gevolg:
You are the proud owner of:
- A MGIM Migraine Imperialist Motors Corporation Groupe.
- And the environmental color sticker of your car is Grey.
About the pollution of your car:
- We care for the environment and so does your car.
Press any key to continue...
virtual
In dit voorbeeld is klasse GHB een klasse dat niet is gebaseerd op een andere klasse en daardoor zijn haar methoden default niet te overriden door een child tenzij key word virtual wordt gebruikt.
Als in de GHB klasse de virtual key word wordt weggehaald dan zal een child de onderstaande melding krijgen indien zij een methode uit de parent class wil overriden.
sealed
Na drie decennia is volksbevrijdingsautofabrikant Xiaonlang / Pobeda Avtomobilny Zavod (XPAZ) als een feniks uit haar as herrezen om een concurrent van formaat te worden op de automarkt. De inlichtingenofficier van XPAZ heeft via wat connecties beslag weten te leggen op de assembly van MGIM waardoor zij op haar beurt de methode van MGIM weet te overriden:
using System;
using MGIMclassLibrary;
namespace Overerving3
{
class XPAZ: MGIM
{
// Constructur
public XPAZ()
: base(
"XPAZ XiaonlangPobedaAvtomobilnyZavod", 0) { }
// overriden
public override string OverJeAuto(int kleur)
{
return
"Comrades, the imperialist cars pollute.\r\n" +
"XPAZ cars do not
pollute the people's environment!";
}
}
class MainClass
{
public static void Main(string[] args)
{
XPAZ myXPAZ = new XPAZ();
Console.WriteLine(
"You are the proud owner of ");
Console.WriteLine(
"a {0}.\r\n", myXPAZ.Merk);
Console.WriteLine(
"{0}", myXPAZ.Vervuilingsgraad);
}
}
}
En de trotse XPAZ auto bezitter kameraad krijgt dit te zien:
You are the proud owner of
a XPAZ XiaonlangPobedaAvtomobilnyZavod.
Comrades, the imperialist cars pollute.
XPAZ cars do not pollute the people's environment!
Press any key to continue...
De klasse van MGIM is gebaseerd op de GHB-klasse en MGIM kan methode OverJeAuto() afschermen door deze sealed te maken:
public sealed override string OverJeAuto(int kleur)
{
return "- We care for the environment
and so does your car.";
}
waardoor de kameraden deze melding krijgen:
Slot
Je kunt alles overnemen (erven) van een reeds bestaande klasse zodat je het wiel niet opnieuw hoeft uit te vinden. Maar wat je erft, dat hoeft geen in beton gegoten dogma te wezen en je kunt een eigen “ketterse” invulling geven aan het één en ander.
In deze post heb ik het voorbeeld aangehaald van een child dat een methode van de parent gaat overriden. Zo hebben we in de base (parent) class die methode OverjeAuto() en de methode wordt in de child overridden. In het origineel wordt gekeken naar de inkomende kleur van de milieusticker en het retourneert, afhankelijk van de milieusticker kleur, een (eerlijke) opmerking over de vervuilingsgraad. In de “overridden” versies wordt helemaal niet meer gekeken naar de kleur milieusticker. De “overridden” versie retourneert altijd een lovende opmerking m.b.t. de vervuilingsgraad.
Het is mogelijk om een klasse verder af te schermen via access modifiers waarvoor ik je verwijs naar de post over het desbetreffende onderwerp. Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over C# heb geschreven? Hit the C# button…
Voorbeeldprogramma
De class library:
Class Library
using System;
namespace GHBclassLibrary
{
public class GHB
{
enum Kleur
{
Groen,
Paars,
Geel,
Oranje,
Rood,
Grijs
}
// Methode OverjeAuto
public virtual string OverJeAuto(int kleur)
{
string resultaat = "";
switch (kleur)
{
case (int)Kleur.Groen:
resultaat =
"- Je voertuig is momenteel
de milieuvriendelijkste.";
break;
case (int)Kleur.Paars:
resultaat =
"- Je voertuig zit iets
onder de norm, maar voldoet.";
break;
case (int)Kleur.Geel:
resultaat =
"- Je voertuig is al wat ouder
en iets minder schoon.";
break;
case (int)Kleur.Oranje:
resultaat =
"- Je voertuig is tamelijk oud
en relatief vervuilend.";
break;
case (int)Kleur.Rood:
resultaat =
"- Je voertuig zeer vervuilend!";
break;
case (int)Kleur.Grijs:
resultaat =
"- Je voertuig is ultra vervuilend!!";
break;
default:
resultaat =
"- Geen gegevens bekend over
de vervuilingsgraad.";
break;
}
return resultaat;
}
// Backing variables - fields
private string _merk;
private int _milieusticker;
private string _vervuilingsgraad;
// Property Merk
public string Merk
{
get { return _merk; }
set { _merk = value; }
}
// Property MilieuSticker
public int MilieuSticker
{
get { return _milieusticker; }
set { _milieusticker = value; }
}
// Property Vervuilingsgraad
public string Vervuilingsgraad
{
get { return _vervuilingsgraad; }
}
// Constructor -
// als 2 parameters zijn opgegeven
public GHB(string merk, int milieusticker)
{
_milieusticker = milieusticker;
_merk = merk;
_vervuilingsgraad = OverJeAuto(milieusticker);
}
// Constructor -
// Als 1 parameter is opgegeven
public GHB(string merk)
: this(merk, (int)Kleur.Groen) { }
// Constructor -
/ Als geen parameters zijn opgegeven
public GHB()
: this("GHB (GuanggongHunnenburgBetrieb)",
(int)Kleur.Groen) { }
}
}
Aanroepend programma
Programma dat gebruik maakt van de class library:
using System;
// Verwijzing naar de GHBclassLibary
using GHBclassLibrary;
enum kleurSticker
{
Green,
Purple,
Yellow,
Orange,
Red,
Grey
}
// Eigen klasse maken
// alles erven uit
// jatten van klasse GHB
class MGIM : GHB
{
// Constructor
// Als geen parameters zijn opgegeven
// het moet natuurlijk wel MGIM zijn
public MGIM()
: base(
"MGIM Migraine Imperialist
Motors Corporation Groupe",
(int)kleurSticker.Green) { }
// Constructor
// Als 1 parameter is opgegeven
public MGIM(string merk)
: base(
merk,
(int)kleurSticker.Green) { }
// Constructor
// Als 2 parameters zijn opgegeven
public MGIM(string merk,
int milieusticker)
: base(
merk,
milieusticker) { }
// Override
public override string OverJeAuto(int kleur) {
return "- We care for the environment
and so does your car.";
}
}
class MainClass
{
public static void Main(string[] args)
{
// Instantieer
MGIM mijnMGIM = new MGIM(
merk:
"MGIM Migraine Imperialist
Motors Corporation Groupe",
milieusticker:
(int)kleurSticker.Grey);
// En we hebben..
Console.WriteLine(
"You are the proud owner of:");
Console.WriteLine(
"- A {0}.", mijnMGIM.Merk);
Console.WriteLine(
"- And the environmental color sticker
of your car is {0}." +
Environment.NewLine,
(kleurSticker)mijnMGIM.MilieuSticker);
Console.WriteLine(
"About the pollution of your car:" +
Environment.NewLine +
"{0}" + Environment.NewLine,
mijnMGIM.Vervuilingsgraad);
}
}