Constructors bij overerving
Wanneer je een object instantiëert van een child-klasse dan gebeuren er meerdere zaken na elkaar, in volgende volgorde:
Eerst wordt de constructor aangeroepen van de basis-klasse.
Gevolgd door de constructors van alle parent-klassen.
Finaal de constructor van de klasse zelf.
Dit is logisch: de child-klasse heeft de "fundering" nodig van z'n parent-klasse om te kunnen werken.
Volgende voorbeeld toont dit in actie:
Indien je vervolgens een object aanmaakt van het type VeldArts
:
Dan zien we de volgorde van constructor-aanroep in het debug output venster:
Er wordt dus verondersteld in dit geval dat er een default constructor in de basis-klasse aanwezig is.
Overloaded constructors en base()
base()
Indien je klasse Soldaat
een overloaded constructor heeft, dan wisten we al dat deze niet automatisch een default constructor heeft. Volgende code zou dus een probleem geven indien je een VeldArts
wilt aanmaken via new VeldArts()
:
Wat je namelijk niet ziet bij child-klassen en hun constructors is dat er eigenlijk een impliciete aanroep naar de constructor van de parent-klasse wordt gedaan. Bij alle constructors staat er eigenlijk :base()
achter, wat je ook zelf kunt schrijven:
Door base()
achter de constructor te zetten ze je: "roep de default constructor van de parent-klasse aan". Je mag hier echter ook parameters meegeven en de compiler zal dan zoeken naar een overloaded constructor in de basis-klasse die deze volgorde van parameters kan accepteren.
We zien hier hoe we ervoor moeten zorgen dat we terug via new VeldArts()
objecten kunnen aanmaken zonder dat we de constructor(s) van Soldaat
moeten aanpassen:
De default constructor van VeldArts
zal de actuele parameter kanSchieten
steeds op true
zetten.
Uiteraard wil je misschien kunnen meegeven bij het aanmaken van een VeldArts
wat de startwaarde van kanSchieten
moet zijn. Dit vereist dat je een overloaded constructor in VeldArts
aanmaakt, die op zijn beurt de overloaded constructor van Soldaat
aanroept.
Je schrijft dan een overloaded constructor in VeldArts
bij:
Merk op hoe we de formele parameter kanSchieten
doorgeven als actuele parameter aan base
-aanroep.
Uiteraard mag je ook de default constructor aanroepen vanuit de child-constructor. Alle combinaties zijn mogelijk, zolang de constructor in kwestie maar bestaat in de parent-klasse.
Een hybride aanpak is ook mogelijk. Volgend voorbeeld toont 2 klassen, Huis
en Gebouw
waarbij we de constructor van Huis
zodanig beschrijven dat deze bepaalde parameters "voor zich houdt" en andere als het ware doorsluist naar de aanroep van z'n parent-klasse:
Vanaf nu kan ik een huis als volgt bouwen:
Volgorde van constructors
De volgorde waarin alles gebeurt in voorgaande voorbeeld is belangrijk om te begrijpen. Er wordt een hele machine in gang gezet wanneer we volgende korte stukje code schrijven:
Start: overloaded constructor van Huis
wordt opgeroepen.
Nog voor dat deze echter iets kan doen, wordt de formele parameter
verdiepingenIn
(die de waarde5
heeft gekregen) doorgegeven als actuele parameter om de constructor van de basis-klasse aan te roepen.De overloaded constructor van
Gebouw
wordt dus aangeroepen.De code van deze constructor wordt uitgevoerd: het aantal verdiepingen van het gebouw/huis wordt ingesteld.
Wanneer het einde van de constructor wordt bereikt, zal er teruggegaan worden naar de constructor van
Huis
.Nu wordt de code van de
Huis
constructor uitgevoerd:HeeftTuintje
krijgt de waardetrue
.
Einde: Finaal keren we terug en staat er nu een gloednieuw object in de heap, wiens geheugenlocatie we kunnen toewijzen aan eenEigenHuis
.
Last updated