3Klassen, objecten en encapsulatie
Klasse = blauwdruk. Object = instantie, gemaakt met new. Een object combineert gegevens (attributen/properties) met gedrag (methodes). Encapsulation: velden private, toegang alleen via properties/methodes die de regels bewaken.
public class Bankrekening { // veld (field): private, met underscore private decimal _saldo; // auto-property, alleen lezen van buiten public string Iban { get; } // property met private setter public string Eigenaar { get; private set; } // berekende (afgeleide) property: /IsRood in UML public bool IsRood => _saldo < 0; public static int Aantal { get; private set; } // static: van de klasse private const decimal Limiet = -500m; // constante public Bankrekening(string iban, string eigenaar) { if (string.IsNullOrWhiteSpace(iban)) throw new ArgumentException("IBAN is verplicht.", nameof(iban)); Iban = iban; Eigenaar = eigenaar; Aantal++; } public void Storten(decimal bedrag) { if (bedrag <= 0) throw new ArgumentOutOfRangeException(nameof(bedrag), "Moet positief zijn."); _saldo += bedrag; } public decimal GetSaldo() => _saldo; public override string ToString() => $"{Iban} ({Eigenaar}): € {_saldo:0.00}"; }
Uitleg
Encapsulation in de praktijk: het saldo is private en verandert alleen via Storten(), die ongeldige bedragen weigert. De constructor bewaakt dat een rekening nooit zonder IBAN bestaat. Aantal is static, dus gedeeld door alle rekeningen.
private set- Iedereen mag lezen, alleen de klasse zelf mag de waarde aanpassen.
nameof- Geeft de naam van een variabele of parameter als tekst, en blijft kloppen als je hem hernoemt.
string.IsNullOrWhiteSpacetrueals de tekst null, leeg of alleen spaties is.throw- Gooit een exception; de methode stopt direct en de fout gaat omhoog naar de aanroeper.
ArgumentException- Voor een ongeldig argument, zoals een lege tekst of verkeerde combinatie.
ArgumentOutOfRangeException- Voor een waarde buiten het toegestane bereik.
override- Vervangt een virtual of abstracte methode van de ouder; tijdens runtime wordt de versie van het echte object gekozen.
private- Alleen zichtbaar binnen deze klasse.
static- Hoort bij de klasse zelf, niet bij één object; gedeeld door alle objecten.
const- Vaste waarde die bij het compileren al vastligt en nooit verandert.
{ get; }- Alleen-lezen property; de waarde wordt in de constructor gezet.
=>- Korte schrijfwijze voor een methode of property die één expressie teruggeeft; in LINQ ook de pijl van een lambda.
#Property met validatie (volledige vorm)
private int _accuPercentage; public int AccuPercentage { get => _accuPercentage; set { if (value is < 0 or > 100) throw new ArgumentOutOfRangeException(nameof(value), "Accupercentage moet tussen 0 en 100 liggen."); _accuPercentage = value; } } // Zet in de constructor via de property (AccuPercentage = x;) // zodat de validatie ook bij aanmaken draait!
Uitleg
Een volledige property met een eigen veld erachter. De setter controleert de waarde voordat hij wordt opgeslagen. Zet de beginwaarde in de constructor via de property en niet via het veld, anders sla je de controle over.
nameof- Geeft de naam van een variabele of parameter als tekst, en blijft kloppen als je hem hernoemt.
throw- Gooit een exception; de methode stopt direct en de fout gaat omhoog naar de aanroeper.
ArgumentOutOfRangeException- Voor een waarde buiten het toegestane bereik.
private- Alleen zichtbaar binnen deze klasse.
value- In een setter: de waarde die iemand probeert toe te kennen.
=>- Korte schrijfwijze voor een methode of property die één expressie teruggeeft; in LINQ ook de pijl van een lambda.
is- Controleert het type (of een patroon) en kan het object meteen in een nieuwe variabele zetten.
#Soorten properties
| Schrijfwijze | Lezen | Schrijven |
|---|---|---|
{ get; set; } | iedereen | iedereen |
{ get; private set; } | iedereen | alleen de klasse |
{ get; protected set; } | iedereen | klasse + subklassen |
{ get; } | iedereen | alleen in constructor |
{ get; init; } | iedereen | bij aanmaken: new X { R = 1 } |
=> expressie | iedereen | nooit (berekend) |
#Access modifiers
| Modifier | Wie mag erbij |
|---|---|
public | iedereen |
private | alleen deze klasse (standaard voor leden) |
protected | deze klasse + subklassen |
internal | hetzelfde project (standaard voor klassen) |
#Constructor-ketens en object-initializer
public Persoon(string naam) : this(naam, 0) { } // roept andere constructor aan public Persoon(string naam, int leeftijd) { ... } var c = new Circle { R = 1 }; // object initializer (init/set)
Uitleg
Met : this(...) roept de ene constructor de andere aan, zodat je de logica maar op één plek hebt. Met een object initializer ({ R = 1 }) vul je properties direct na het aanmaken; dat werkt voor properties met set of init.
this(...)- Roept een andere constructor van dezelfde klasse aan.
var- De compiler leidt het type zelf af uit de rechterkant.
new. Destructor (~Klasse()): opruimen, in C# zelden nodig (garbage collector; voor bestanden gebruik je using). Object state = de huidige waarden van de velden van een object.