Zie Scherp Scherper - Hoofdstuk 9
Na dit hoofdstuk kan je:
public/private) correct gebruikenDateTime-klasseTot nu toe programmeerden we gestructureerd (procedureel): loops, methoden, beslissingen.
Alles draait voortaan rond klassen en objecten.
Waarschuwing
Twee balletjes? Dan moet je bijna elke lijn verdubbelen (bal2X, v2X, …). Bij honderd balletjes wordt het een ramp.
We stoppen de data en het gedrag van een balletje samen in één klasse.
Tip
Honderd balletjes? Een array van Balletje en twee loopjes. Zo simpel.
De logica zit in de objecten zelf. Elk object is verantwoordelijk voor zijn eigen gedrag, op basis van zijn eigen interne toestand.
In de Main zeg je gewoon: “update jezelf” en “teken jezelf”.
Duizend mammoeten en sabeltandtijgers! Ik doe een voorspelling: van alle hoofdstukken wordt dit het hoofdstuk waar je het meest je tanden op stukbijt.
Hou vol, geef niet te snel op, en kom hier geregeld terug.
Tip
Het grondplan van een huis is de klasse. De tien huizen die je ermee bouwt zijn de objecten: elk met eigen bakstenen en rolluiken.
Een object heeft:
Tip
Zoek in een opgave naar de zelfstandige naamwoorden: dat zijn vaak je klassen.
Het black-box-principe, denk aan een auto:
Hoe minder de buitenwereld moet weten om met een object te werken, hoe beter.
De vier pijlers van OOP:
Opmerking
Steve Jobs over objecten: “They encapsulate complexity, and the interfaces to that complexity are high level.”
.cs-bestand (Project - Add class…)internal voornew keyword (zoals eerder bij Random)new maakt het object in het geheugen en geeft het adres terugTip
Klassen zijn dus gewoon een nieuw, krachtiger datatype: variabelen die meerdere waarden én methoden bundelen.
Waarschuwing
Een null-object tóch gebruiken geeft een NullReferenceException: dé klassieker bij beginnende OOP’ers. Je vergat new.
static voor methoden in zo’n klassepublic maakt de methode bruikbaar voor de buitenwereldprivate: enkel zichtbaar binnen de klasse zelf (de standaard als je niets schrijft)public: iedereen kan eraaninternal: enkel binnen het huidige project; protected: voor overerving (later)Belangrijk
Zet altijd expliciet een access modifier. Niets schrijven betekent private, maar dat expliciet maken leest veel duidelijker.
Interne hulpcode scherm je af zodat anderen ze niet per ongeluk aanroepen. Binnen de klasse mag je ze wél gebruiken:
Elke instantie houdt zijn eigen toestand bij in een instantievariabele:
Verjong je het ene object, dan blijft het andere ongemoeid: elk object heeft zijn eigen geboorteJaar.
Ik zag je denken: “zal ik die instantievariabele eens public maken?” Niet doen. Simpel.
Een public instantievariabele laat de buitenwereld om het even welke waarde toekennen (adil.geboortejaar = -12000;) en breekt zo je klasse.
Belangrijk
Toegang regel je via properties en methoden, nooit via een publieke instantievariabele.
Een methode kan illegale waarden tegenhouden:
Een object beschermt zichzelf: de buitenwereld kan zijn werking niet zomaar om zeep helpen.
Darth Vader is een SithLord met een geheime naam en een hoeveelheid energie (nooit onder 0):
Tip
Properties zijn de moderne C#-manier om de interne staat gecontroleerd in en uit te lezen, in plaats van losse methoden.
public en begint met een hoofdletterset zit de waarde in het keyword valueDe property treedt op als wachter:
palpatine.Energie = -1; heeft nu geen effect: negatieve energie wordt geweigerd.
get (bv. een pincode)setprivate set: enkel intern aanpasbaargetTip
Pas, ook binnen de klasse, je instantievariabele aan via de property, zodat je controles niet omzeilt.
Een read-only property die data berekent (geen eigen instantievariabele):
Tip
Geen extra controle nodig? Dan volstaat een auto-property, zonder zichtbare instantievariabele:
Tip
Begin vaak met auto-properties; vervang ze door full properties zodra je controle of transformatie nodig hebt. (prop + tab + tab in VS.)
DateTime.Now is een static propertynew DateTime(...) gebruikt een constructor (hoofdstuk 11) om het object meteen in te stellenAddDays, AddHours, AddYears, … geven telkens een nieuw DateTime-object terugMonth en DayOfWeek zijn read-onlyTwee DateTime-objecten aftrekken geeft een TimeSpan:
Optellen van twee datums kan niet, aftrekken wel.
Bouw een mini-fitness-app waarin een sporter zijn trainingen bijhoudt. Een klasse Loper met:
NaamAantalLopen, TotaleAfstand en TotaleTijd (alleen leesbaar naar buiten)RegistreerTraining(afstand, tijd)Tip
Gebruik properties met begrenzing (clamping): een negatieve afstand of tijd weiger je in de set. Zo beschermt het object zichzelf, precies de kern van dit hoofdstuk.
We doorliepen vier fasen:
DateTime als voorproefje van een krachtige klassenew)get/set/value) of autonew, dan is je object null en krijg je een NullReferenceExceptionDateTime toont hoe krachtig een goed ontworpen klasse isTip
Volgende halte: geheugenmanagement en uitzonderingen (exceptions).
Kennisclips
Dezelfde concepten uit dit hoofdstuk, maar dan in andere talen. Handig om later code in Python of JavaScript te leren lezen.
Dat alle code in een klasse moet, deelt C# met Java. Python en JavaScript zijn losser: daar mag je gewoon losse code en functies schrijven.
OOP is daar een keuze, geen verplichting. In C bestaat het begrip klasse zelfs niet. C# zit aan het strenge eind.
Java kent geen properties: daar schrijf je met de hand een aparte getter en setter:
Python zit dichter bij C# met de @property-decorator: methoden die je van buiten gebruikt alsof het een gewone variabele is. In beide gevallen verberg je de instantievariabele en regel je de toegang.
Een handige samenvattende poster (Opgelet: gemaakt m.b.v. ChatGPT Image Gen 2).