Klasse (informatica)
Een klasse in de zin van de objectoriëntatie is een mechanisme dat in bepaalde, objectgeoriënteerde programmeertalen gebruikt wordt om de toestandsruimte en interface van een verzameling objecten vast te leggen. Een klasse wordt ook wel omschreven als een sjabloon voor objecten.
Klasse versus object
[bewerken | brontekst bewerken]Objectgeoriënteerde programmeertalen zijn er, over het algemeen, in twee soorten:
- Objectgebaseerde talen
- objectgeoriënteerde programmeertalen die geen gebruik maken van het concept klasse.
- Klasse-gebaseerde talen
- objectgeoriënteerde programmeertalen die zowel klassen als objecten kennen.
Objectgebaseerde talen definiëren programma's geheel in termen van objecten. Objecten ontstaan als kopieën van objecten en gebruiken uitbreiding om van definitie te veranderen.
Klasse-gebaseerde talen scheiden het concept van de definitie van de vorm van objecten en het eigenlijke gebruik van objecten. In klasse-gebaseerde talen vormt een klasse de definitie van een hele verzameling objecten: hun toestand, hun operaties, hun interface worden vastgelegd door de klasse. Een klasse van deze soort is, bij wijze van spreken, het origineel dat op een kopieerapparaat gelegd wordt. Objecten zijn de kopieën die van dit origineel gemaakt worden -- ze beschikken over een eigen kopie van dezelfde toestandsruimte en dezelfde operaties. Ze voldoen ook aan dezelfde interface als vastgelegd door de klasse.
Het onderscheid klasse versus object is een formalisatie van het onderscheid tussen het statische karakter van de definitie van objecten en het dynamische karakter van hun gebruik. Ditzelfde onderscheid komt overigens terug in de verschillende typen diagrammen binnen de Unified Modeling Language. Omdat klassen het statische karakter van objecten vastleggen, worden ze binnen de object-georiënteerde talen meestal niet beschouwd als actieve entiteiten die in de werking van het programma deelnemen (de zogenaamde first-class citizens).
Dat laatste is overigens geen harde regel. Er zijn verschillende talen die over objecten beschikken die weer klassen voorstellen binnen het actieve programma. Deze objecten geven dan vaak weer toegang tot verschillende eigenschappen van de klasse die ze voorstellen -- waaronder de mogelijkheid om dynamisch nieuwe objecten te genereren. Deze objecten-die-klassen-voorstellen (vaak reflectieve of introspectieve objecten genaamd) zijn natuurlijk zelf ook weer instanties van een klasse. Die weer voorgesteld kan worden door een object. Bij het ontwerp van een object-georiënteerde programmeertaal met reflectie is deze lus-structuur vaak een aardige puzzel.
Klasse versus type
[bewerken | brontekst bewerken]Een heel apart vraagstuk is dat van het type van objecten binnen programma's. Ook op dit gebied zijn er twee algemene vormen:
- Het type van objecten komt overeen met hun klasse.
- Het type van een object staat los van zijn klasse.
Binnen de object-oriëntatie bestaat het concept van de overerving. Meestal wordt hiermee type-overerving bedoeld. Het type van een object bepaalt de manieren waarop een object binnen een programma gebruikt mag worden als argument aan een methode-aanroep. Door type-overerving ontstaat een hiërarchie binnen een programma van objecten die super- of subtypen van elkaar zijn.
Een tweede, mogelijke hiërarchie is die van de overerving van operaties of implementaties. Deze klasse-overerving bestaat eruit dat objecten van een kindklasse de implementatie van een operatie delen met hun superklasse. Dit is duidelijk een ander soort overerving dan type-overerving: dat twee objecten een operatie of implementatie delen, wil niet zeggen dat beide objecten als argumenten aan dezelfde methode mogen worden doorgegeven.
In talen waar type-overerving overeenkomt met klasse-overerving, bestaat maar een hiërarchie. Voorbeelden van dergelijke talen zijn Java en C++. Een object dat qua type een kind is van een ander object, is ook qua klasse (implementaties) een kind van dat object en omgekeerd.
In talen waar deze hiërarchieën niet overeenkomen, zijn zeer complexe relaties tussen objecten binnen een programma mogelijk. Objecten die qua type overeenkomen, kunnen soms een andere verzameling operaties aanbieden. Een voorbeeld van een dergelijke taal is Python.
Bij reflectie treedt een interessant fenomeen op: de typehiërarchie tussen objecten en hun bijbehorende, reflectieve objecten is niet hetzelfde. Als een object A qua type een kind is van object B, dan is reflectie_A niet een kind van reflectie_B. De reden hiervoor is dat het vasthouden van dezelfde hiërarchie binnen reflectie een probleem oplevert aan de top van de boom. Stel dat een bepaald object het meest algemene type heeft binnen een taal. Welk type heeft dan het reflecterende object van dat object? Daarnaast bestaat er binnen de talen met een enkele hiërarchie nog een praktisch probleem, dat reflecterende objecten meestal instanties zijn van de klasse die reflecterende objecten definieert en dat ze dus hetzelfde type moeten hebben.