Zie Scherp Scherper - Hoofdstuk 15
Na dit hoofdstuk kan je:
Listthis-keyword gebruikenTip
Eigenlijk niets nieuws: je deed dit waarschijnlijk al, zonder de naam te kennen.
Een object in een ander object gebruiken heet een associatie. Het verschil zit in de levensduur van het interne object:
Belangrijk
Een boek is geen pagina. Een boek heeft pagina’s. Dat is dus associatie, geen overerving. (“Heeft meerdere” wijst op een array of List.)
De twee relaties sluiten elkaar niet uit:
Auto heeft een Motor (compositie)Sportwagen is een Auto (overerving)Sportwagen heeft via overerving ook een MotorTip
Overerving en compositie werken samen: de child erft de associaties van zijn parent.
Compositie: volle ruit aan de kant van het omliggende object.
Aggregatie: lege ruit. Een getal duidt de verhouding aan.
Een PC heeft een HardeSchijf, dus zit er in PC een instantievariabele van het type HardeSchijf:
Vergeet niet die HardeSchijf ook te instantiëren, anders blijft hij de hele levensduur null.
Meteen bij de instantievariabele, of via de constructor:
Sterft de PC, dan sterft de interne schijf mee: dat is compositie.
Maak het object buiten de PC aan en plug het in via een property:
Er blijft een externe referentie (schijf), dus de GC ruimt hem niet op met de PC: dat is aggregatie.
Het interne object staat apart in de heap; de PC bewaart enkel een referentie ernaar.
Compositie geeft dus geen groot monolithisch object: alles blijft netjes verbonden via referenties.
Waarschuwing
Een intern object aanspreken dat nooit werd aangemaakt, geeft een NullReferenceException. Controleer dus op null.
Een boek heeft veel pagina’s, dus een array of List. Hou de collectie privé en bied een eigen methode aan:
Belangrijk
Een interne List rechtstreeks via een publieke set aanbieden is riskant: iemand kan dan zomaar Clear() aanroepen. Hou het een blackbox.
Favor composition over inheritance.
In de praktijk gebruik je veel vaker een heeft-een dan een is-een-relatie.
Belangrijk
patient.Hart = donor.Hart; kopieert niet: beide verwijzen nu naar hetzelfde Hart-object. Een object delen is geen object kopiëren. Wees dus geen Dokter Frankenstein van C#: te veel compositie maakt een klasse minder herbruikbaar.
this is de referentie naar het huidige object. Drie toepassingen:
: this(...), hoofdstuk 11)Belangrijk
this werkt enkel in een instance-context (gewone methoden, properties, constructors). In een static methode bestaat er geen “huidig object”.
this.Levens haalt de property, ook al heet de parameter net zo.
Tip
Beter nog: geef je parameter gewoon een andere naam, dan heb je this hier niet eens nodig.
Het object geeft zichzelf (this) door aan een externe methode, zodat een werknemer zelf kan checken of die promoveerbaar is.
In een spel heeft een Held twee handen, elk met 0 of 1 Wapen dat schade doet:
Tip
Een lege hand is gewoon null. Reik je het wapen door aan een andere held, dan is het aggregatie: het wapen leeft los van de held.
List, liefst achter een nette blackboxthis verwijst naar het huidige object; favor composition over inheritanceTip
Volgende halte: polymorfisme, waar één naam vele vormen aanneemt.
Kennisclips
Dezelfde concepten uit dit hoofdstuk, maar dan in andere talen. Handig om later code in Python of JavaScript te leren lezen.
In Python werkt de “heeft een”-relatie quasi identiek: gewoon een object als instantievariabele.
“Een object in een ander object” is geen C#-eigenaardigheid, maar geldt in elke OO-taal. Net als favor composition over inheritance.
In Python bestaat er geen impliciet this: je geeft het huidige object expliciet mee als eerste parameter, traditioneel self.
C# regelt this verborgen via de compiler; Python toont datzelfde object gewoon als eerste parameter. JavaScript heeft wél this, maar met beruchte binding-regels: waarnaar het verwijst hangt af van hoe je een functie aanroept.
Een handige samenvattende poster (Opgelet: gemaakt m.b.v. ChatGPT Image Gen 2).