Skip to content

13. De klassen

Image

Hier introduceren we de klassen van ECMAScript 6. Allereerst laten we zien dat de functies al als klassen kunnen worden gebruikt.

13.1. script [class-00]

Het volgende script toont een ongebruikelijk gebruik van functies. Ze worden hier als objecten gebruikt.


'use strict';
// een functie kan als een object worden gebruikt

// een lege schil
function f() {

}
// waaraan van buitenaf eigenschappen worden toegekend
f.prop1 = "val1";
f.show = function () {
  console.log(this.prop1);
}
// gebruik van f
f.show();

// een functie g die als een klasse functioneert
function g() {
  this.prop2 = "val2";
  this.show = function () {
    console.log(this.prop2);
  }
}
// instantiëren van de functie met [new]
new g().show();

Opmerkingen

  • regels 5-7: de body van de functie f definieert geen eigenschappen;
  • regels 9-12: er worden van buitenaf eigenschappen aan de functie f toegekend;
  • regel 14: gebruik van de functie (object) f. Merk op dat we niet [f()] schrijven, maar gewoon [f]. Dit is de notatie voor een object;
  • regels 17-22: er wordt een functie [g] gedefinieerd alsof het een klasse met eigenschappen en methoden is;
  • regel 24: de functie [g] wordt geïnstantieerd door [new g()];

Uitvoeringsresultaten


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2

ES6 heeft het concept van klassen geïntroduceerd, waardoor we voortaan niet meer via functies hoeven te werken om klassen te krijgen.

13.2. script [class-01]

Het script [class-01] introduceert een klasse [Personne]:


// klasse
class Personne {

  // constructor
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // getters en setters
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString en JSON
  toString() {
    return JSON.stringify(this);
  }
}

// aanroep van de klasse
function main() {
  const personne = new Personne("Poirot", "Hercule", 66);
  console.log("personne=", personne.toString(), typeof (personne), personne instanceof (Personne));
}

// aanroep van main
main();

Opmerkingen

  • regel 2: het sleutelwoord [class] duidt een klasse aan;
  • regels 5-9: het sleutelwoord [constructor] verwijst naar de constructor van de klasse. Er kan er hooguit één zijn. Deze dient om een instantie van de klasse aan te maken en te initialiseren. Merk op dat er geen declaratie is van de eigenschappen [nom, prénom, âge];
  • regels 11-36: eigenschappen van de klasse. Hier vinden we zaken terug die we al hebben gezien in paragraaf 4 over objecten, op pagina 44. Alleen de syntaxis verschilt;
  • regel 41: aanmaken van een object van het type [Personne]. Vanaf nu wordt het object [personne] gebruikt als een letterlijk object. [typeof (personne)] is gelijk aan „object” en de uitdrukking [personne instanceof (Personne)] is waar. Het is dus mogelijk om het exacte type van een klasse-instantie te achterhalen;

Uitvoeringsresultaten


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-01.js"
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66} object true

13.3. script [class-02]

Dit script laat zien dat het mogelijk is om van een klasse te erven met het sleutelwoord [extends].

Allereerst isoleren we de klasse [Personne] in een module [Personne.js]:


// klasse
class Personne {

  // constructor
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // getters en setters
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString en JSON
  toString() {
    return JSON.stringify(this);
  }
}
// klasse exporteren
export default Personne;
  • regel 39: we exporteren de klasse [Personne] zodat scripts deze kunnen importeren;

Het script [class-02] maakt een klasse [Enseignant] aan, die is afgeleid van de klasse [Personne]:


// imports
import Personne from './Personne';

// klasse
class Enseignant extends Personne {

  // constructor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters en setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// aanroep van de klasse
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// aanroep van main
main();

Opmerkingen

  • regel 2: de klasse [Personne] wordt geïmporteerd uit de module [Personne.js], die zich in dezelfde map bevindt als [class-02];
  • regel 5: de klasse [Enseignant] breidt de klasse [Personne] uit (erft van) met het sleutelwoord [extends]: deze voegt er een eigenschap [_discipline] aan toe, met de bijbehorende getter- en setter-methoden;
  • regels 8-11: de constructor van de klasse [Enseignant] ontvangt vier waarden om de vier eigenschappen van de klasse te initialiseren;
  • regel 9: het sleutelwoord [super] roept de constructor van de bovenliggende klasse [Personne] aan, die vervolgens de eigenschappen [_nom, _prénom, _âge] initialiseert;
  • regel 10: de eigenschap [_discipline], die bij de klasse [Enseignant] hoort, wordt geïnitialiseerd;
  • regels 14-19: de getter en de setter van de eigenschap [_discipline];
  • regel 25: er wordt een object van het type [Enseignant] aangemaakt;
  • regel 26: de methode [enseignant.toString()] wordt gebruikt. De klasse [Enseignant] beschikt niet over deze methode. In dat geval wordt automatisch de methode van de bovenliggende klasse gebruikt. Deze methode zorgt ervoor dat de uitdrukking [JSON.stringify(this)] – waarbij [this] hier een object van het type [Enseignant] is en geen object van het type [Personne] – wordt weergegeven. Dit wordt in objectgeoriënteerd programmeren het polymorfisme van klassen genoemd. Een groot woord voor JavaScript, dat geen objectgeoriënteerde taal is. Toch doet JavaScript hier wat er van verwacht wordt: het geeft inderdaad een leraar weer;

De resultaten van de uitvoering zijn als volgt:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-02.js"
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true
  • regel 2: JavaScript herkent inderdaad dat de variabele [enseignant] van het type [Enseignant] is;

13.4. script [class-03]

Het script [class-03] laat zien dat een afgeleide klasse eigenschappen en methoden van de bovenliggende klasse kan herdefiniëren. Hier herdefiniëren we de methode [toString] van de bovenliggende klasse:


// imports
import Personne from './Personne';

// klasse
class Enseignant extends Personne {

  // constructor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters en setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

  // herdefinitie van toString
  toString() {
    return "[Enseignant]" + JSON.stringify(this);
  }
}

// aanroep van de klasse
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// aanroep van main
main();

De resultaten van de uitvoering zijn als volgt:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-03.js"
enseignant= [Enseignant]{"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true

13.5. script [class-04]

Het script [class-04] toont opnieuw hoe polymorfisme werkt: waar een functie een formele parameter van het type [Personne] verwacht, kan een afgeleid type zoals [Enseignant] worden doorgegeven. Door de afleiding beschikt het type [Enseignant] namelijk over alle attributen van het type [Personne].

Allereerst isoleren we het type [Enseignant] in een module [Enseignant.js]:


// imports
import Personne from './Personne';

// klasse
class Enseignant extends Personne {

  // constructor
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // getters en setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// klasse exporteren
export default Enseignant;
  • regel 24: de klasse [Enseignant] wordt geëxporteerd zodat andere scripts deze kunnen importeren;

Het script [class-04] ziet er als volgt uit:


// imports
import Enseignant from './Enseignant';
import Personne from './Personne';

// functie die één persoon als parameter accepteert
function show(personne) {
  // in alle gevallen
  console.log("paramètre=", personne.toString(), typeof (personne));
  // instantie van Personne
  if (personne instanceof Personne) {
    console.log("personne=", personne.toString());
  }
  // instantie van Docent
  if (personne instanceof Enseignant) {
    console.log("enseignant=", personne.toString());
  }
}

// aanroep van show met een docent
show(new Enseignant("Poirot", "Hercule", 66, "détective"));
show(new Personne("Marple", "Miss", 70));
  • regel 6: de functie [show] verwacht een type [Personne] of een daarvan afgeleid type;
  • regel 8: de tekenreeks van de parameter en het type ervan worden weergegeven. We zullen [object] aantreffen;
  • regels 10-16: we kunnen vaststellen of het om een type [Personne] of een type [Enseignant] gaat. De code kan dus worden aangepast aan het werkelijke type van de parameter;

De resultaten van de uitvoering zijn als volgt:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-04.js"
paramètre= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
paramètre= {"_nom":"Marple","_prénom":"Miss","_âge":70} object
personne= {"_nom":"Marple","_prénom":"Miss","_âge":70}
  • regels 4 en 6: JavaScript herkent het type van de klasse-instanties correct;