Zie Scherp Scherper
OefeningenThe Corona filesHandboek backup
  • H0: Introductie
    • Introductie
    • Dit boek in papier?
    • Nuttige extras
  • H1: De eerste stappen
    • Introductie tot C#
    • Werken met Visual Studio
    • Je eerste programma
    • Input verwerken met ReadLine
    • Fouten in je code
    • Kleuren in Console
    • Meer weten
  • H2: De basisconcepten van C#
    • De essentie van C#
    • Datatypes
    • Variabelen
    • Expressies en operators
    • Const(ant)
    • Solutions en projecten
    • Meer weten
  • H3: Tekst gebruiken in code
    • Strings en chars
    • Escape characters
    • Strings samenvoegen
    • Unicode tonen
    • Environment bibliotheek
    • Meer weten
  • H4: Werken met data
    • Casting, conversie en parsing
    • Input verwerken en omzetten
    • Math-library en berekeningen
    • Over afronden
    • Random
    • Debuggen
    • Meer weten
  • H5: Beslissingen
    • Beslissingen intro
    • Booleanse logica en operators
    • If
    • Scope van variabelen
    • Switch
    • enum
    • Meer weten
  • H6: Herhalingen Herhalingen Herhalingen
    • Loops intro
    • While en Do While
    • For
    • Nesting
    • Meer weten
  • H7: Methoden
    • Methoden intro
    • Bibliotheken
    • Geavanceerde methodetechnieken
    • Meer weten
  • H8: Arrays
    • Array principes
    • Arrays en geheugen
    • System.Array
    • Algoritmes met arrays
    • Strings en arrays
    • Arrays en methoden
    • N-dimensionale arrays
    • Jagged arrays
    • Meer weten
  • H9: Object Oriented Programming
    • OOP Intro
    • Klassen en objecten in C#
    • Methoden en access modifiers
    • Full properties
    • Auto-properties
    • DateTime: leren werken met objecten
    • Meer weten
  • H10: Geheugenmanagement, uitzonderingen en namespaces
    • Stack en Heap
    • Objecten en methoden
    • Null en NullReferenceException
    • Namespaces en using
    • Exception handling
    • Waar exceptions plaatsen?
    • Meer weten
  • H11: Gevorderde klasseconcepten
    • Constructors en de default Constructors
    • Overloaded Constructors
    • Object Initializer Syntax
    • Static
    • Meer weten
  • H12: Arrays en klassen
    • Arrays van objecten
    • List
    • Foreach en var
    • Nuttige collection klassen
    • Meer weten
  • H13: Overerving
    • Overerving intro
    • Constructors bij overerving
    • Virtual en override
    • Base keyword
    • Meer weten
  • H14: Gevorderde overervingsconcepten
    • System.Object
    • Abstract
    • Eigen exceptions maken
    • Kennisclips
  • H15: Compositie en aggregatie
    • Compositie
    • this keyword
    • Meer weten
  • H16: Polymorfisme
    • Polymorfisme
    • Polymorfisme in de praktijk
    • Is en As keywords
    • Objecten vergelijken: alles komt samen
    • Meer weten
  • H17: Interfaces
    • Interface intro
    • Interfaces voorbeeld met president
    • Interfaces in de praktijk
    • Interfaces en polymorfisme
    • Meer weten
  • H18: Bestandsverwerking
    • Werken met bestanden
    • Schrijven en lezen
    • FileInfo klasse
    • Klassen serialiseren met json
    • Meer weten
  • Conclusie
    • Je hebt het gehaald
    • En nu?
  • Kennicslips
    • H1 - H8
    • H9 - H17
  • Appendix
    • Visual Studio snippets
    • VS Code for Mac installeren
    • Regions
    • String.Format
    • Out en Ref parameters
    • Operator overloading
    • Expression bodied members
    • Generics
    • struct en record
    • Een installer maken
  • Coding guidelines
    • Afspraken
    • Minpunten voor: Compileert niet
    • Minpunten voor: Klassen in 1 bestand
    • Minpunten voor: Redundante code
    • Minpunten voor: Bladspiegel
    • Minpunten voor: Naamgeving
    • Minpunten voor: goto, break en continue
    • Minpunten voor: Linq gebruiken
    • Minpunten voor: Methoden in methoden
    • Minpunten voor: Toplevel statements
Powered by GitBook
On this page
  • Overloaded constructors en base()
  • Volgorde van constructors

Was this helpful?

  1. H13: Overerving

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:

internal class Soldaat
{
   public Soldaat() 
   {
      Debug.WriteLine("Soldaat is aangemaakt.");
   }
}

internal class VeldArts : Soldaat
{
   public VeldArts()
   {
      Debug.WriteLine("Veldarts is aangemaakt.");
   }
}

Indien je vervolgens een object aanmaakt van het type VeldArts:

VeldArts RexGregor = new VeldArts();

Dan zien we de volgorde van constructor-aanroep in het debug output venster:

Soldaat is aangemaakt.
Veldarts is aangemaakt.

Er wordt dus verondersteld in dit geval dat er een default constructor in de basis-klasse aanwezig is.

Overloaded constructors en 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():

internal class Soldaat
{
   public Soldaat(bool kanSchieten) 
   {
      //Doe soldaten dingen
   }
}

internal class VeldArts:Soldaat
{
   public VeldArts()
   {
      Debug.WriteLine("Veldarts is aangemaakt.");
   }
}

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:

internal class VeldArts:Soldaat
{
   public VeldArts(): base()
   {
      Debug.WriteLine("Veldarts is aangemaakt.");
   }
}

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:

internal class Soldaat
{
   public Soldaat(bool kanSchieten) 
   {
      //Doe soldaten dingen
   }
}
internal class VeldArts:Soldaat
{
   public VeldArts():base(true)
   {
      Debug.WriteLine("Veldarts is aangemaakt.");
   }
}

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:

internal class Soldaat
{
   public Soldaat(bool kanSchieten) 
   {
      //Doe soldaten dingen
   }
}

internal class VeldArts:Soldaat
{
   public VeldArts(bool kanSchieten): base(kanSchieten)
   {} 

   public VeldArts():base(true) //Default
   {
      Debug.WriteLine("Veldarts is aangemaakt.");
   }
}

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:

internal class Gebouw
{
   public int AantalVerdiepingen { get; private set; }
   public Gebouw(int verdiepingenIn)
   {
      AantalVerdiepingen = verdiepingenIn;
   }
}
internal class Huis: Gebouw
{
   public bool HeeftTuintje { get; private set; };
   public Huis(bool heeftTuin, int aantalVer): base(aantalVer)
   {
      HeeftTuintje = heeftTuin;
   }
}

Vanaf nu kan ik een huis als volgt bouwen:

Huis peperkoekenHuis = new Huis(true, 1);

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:

Huis eenEigenHuis = new Huis(true,5);

Start: overloaded constructor van Huis wordt opgeroepen.

  1. Nog voor dat deze echter iets kan doen, wordt de formele parameter verdiepingenIn (die de waarde 5 heeft gekregen) doorgegeven als actuele parameter om de constructor van de basis-klasse aan te roepen.

  2. De overloaded constructor van Gebouw wordt dus aangeroepen.

  3. De code van deze constructor wordt uitgevoerd: het aantal verdiepingen van het gebouw/huis wordt ingesteld.

  4. Wanneer het einde van de constructor wordt bereikt, zal er teruggegaan worden naar de constructor van Huis.

  5. Nu wordt de code van de Huis constructor uitgevoerd: HeeftTuintje krijgt de waarde true.

Einde: Finaal keren we terug en staat er nu een gloednieuw object in de heap, wiens geheugenlocatie we kunnen toewijzen aan eenEigenHuis.

PreviousOvererving introNextVirtual en override

Last updated 10 months ago

Was this helpful?

Achter de schermen gebeurt er aardig wat bij overerving wanneer we een object aanmaken.