Classes & objecten


  1. Voorbeeld
  2. Classbeschrijving maken
    1. Methods
    2. Constructor
    3. Variabelen
  3. Object maken
  4. Meerdere objecten maken
  5. Meerdere objecten in een array
  6. Eigenschappen meegeven aan een object
  7. Eigenschappen meegeven aan methods

Een class is een manier om bepaalde functies en variabelen die samenhangen in één keer te beschrijven. Dit doe je zodat je er makkelijk heel veel van kunt maken zonder daar steeds allerlei nieuwe variabelen voor te declareren.

Binnen programmeertalen zijn objecten taalconstructies waarmee je groepen van verschillende elementen kunt maken. Dat doe je niet achteraf door elementen toe te voegen aan een groep, maar van te voren door een klasse te beschrijven en vervolgens dingen te maken die de eigenschappen van die klasse hebben. Die dingen noem je objecten. Binnen JavaScript bestaat er nog een andere vorm van objecten. Als we het in dit hoofdstuk over objecten hebben bedoelen we de hierboven beschreven vorm.


1. Voorbeeld

Als we in P5.js een blokje op het scherm willen tekenen dan kunnen we de functie rect aanroepen om een rechthoek te tekenen. We moeten elke keer bedenken waar de rechthoek moet staan (x- en y-positie) en hoe groot hij is (breedte en hoogte (b,h)) Verder moeten we aangeven in welke kleur hij getekend moet worden, of er een rand omheen moet en als we hem willen verplaatsen of laten knipperen moet daar ook code voor worden geschreven.

Dat is voor één blokje nog wel te doen, maar als je meerdere blokjes wil tekenen die elkaar onderling beïnvloeden, dan wordt de code al gauw onoverzichtelijk.

Dat kan ook anders: we beschrijven eerst het algemene gedrag van een blokje in een object en daarna kunnen we zo veel van die blokjes maken als we nodig hebben.

⬆️


2. Ontwerp: een class-beschrijving maken

Vraag jezelf van te voren af: welke algemene eigenschappen heeft een blokje en welke functionaliteiten moet deze krijgen? In dit geval zijn de eigenschappen positie, afmeting, kleur, omlijning. De belangrijste functionaliteit is dat het blokje getekend moet worden.

class Block {
  constructor() {
    this.x = random(width); //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255), random(255), random(255)); //kleur
  }

  draw() {
    fill(this.blockColor);
    rect(this.x, this.y, this.b, this.h);
  }
}

De hierboven beschreven code is de minimale opzet van een class. Het aanmaken van de class gebeurt met het woord class waarna de naam van de class volgt. Het is een goed gebruik, en in sommige gevallen zelfs verplicht, om deze naam met een hoofdletter te laten beginnen.
let op: in tegenstelling tot bij het maken van een functie volgen er geen () na het maken van een class, het is immers geen functie, waar de () wel verplicht zijn.

2.1 Methods

Vervolgens kan je binnen een class met behulp van verschillende methods eigenschappen en gedrag van een object gaan bepalen. Een method is een vergelijkbare constructie als een functie, maar dan binnen een object. let op: in tegenstelling tot bij het maken van een functie hoef je niet het woord function op te schrijven voordat je een method binnen een class aanmaakt.

2.2 Constructor

Een belangrijke method is de constructor(). De constructor wordt aangeroepen zodra je vanuit de class-beschrijving een nieuw object aanmaakt. Je kan de constructor vergelijken met de setup()-functie uit P5.js: De plek om algemene eigenschappen te beschrijven.

2.3 Variabelen

variabelen die je binnen een class wilt gebruiken definieer je net anders dan in normale JavaScript-code. Dit doe je door this. te gebruiken. Met this. zorg je ervoor dat de variabele uiteindelijk alleen bekend is binnen het object dat je hebt aangemaakt, en daarmee dus ook exclusief is voor dat object. Zo kan je bij het maken van meerdere objecten uit één class-omschrijving er voor zorgen dat ieder object unieke eigenschappen heeft.

⬆️


3. Realisatie: een object maken

Een nieuw object wordt doormiddel van new met daaropvolgend de naam van de class, afgesloten met (). Een nieuwe object plaats je in een variabele, zodat je er later nog iets mee kunt. De constructor-method wordt automatisch uitgevoerd zodra je op deze manier een object maakt van een classbeschrijving.

Voorbeeld: myBlock = new Block();

Zodra je het object hebt gemaakt kan je de methods die je binnen dit object hebt gemaakt aanroepen op de volgende manier: naam van de variabele.naam van de functie().

Voorbeeld myBlock.draw();.

In het hieronder beschreven voorbeeld wordt het object aangemaakt in de setupfunctie, dit kan niet daarboven omdat de inhoud van de class-beschrijving nog niet bekend is als dat deel van de code uitgevoerd wordt. Zodra de setup()-functie wordt uitgevoerd is die beschrijving wel bekend en kan je het object maken.

//lege variabele waar straks een object in opgeslagen wordt
let myBlock;

function setup() {
  createCanvas(600 ,800);
  //hieronder maken we een nieuw object vanuit de class Block
  // op dat moment wordt de constructor()-method aangeroepen
  myBlock = new Block();
}

function draw() {
  background(200);
  //hier wordt de draw()-method uti de classomschrijving uitgevoerd
  myBlock.draw();
}

//class-beschrijving:
class Block {
  constructor() {
    this.x = random(width); //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255), random(255), random(255)); //kleur
  }

  draw() {
    fill(this.blockColor);
    rect(this.x, this.y, this.w, this,h);
  }
}

⬆️


4. Meerdere objecten maken

Zoals je hieronder ziet kan je meerdere variabelen aanmaken en die vervolgens allemaal vullen met een nieuw object. Op die manier maak je dus met behulp van een class-beschrijving meerdere objecten aan. Doordat in de constructor()-method de positie, grootte en kleur willekeurig wordt bepaald, zal elk object, myBlock1, myBlock2 en myBlock3 een andere positie, grootte en kleur hebben.

let myBlock1;
let myBlock2;
let myBlock3;

function setup() {
  createCanvas(800,600);
  myBlock1 = new Block();
  myBlock2 = new Block();
  myBlock3 = new Block();
}

function draw() {
  background(200);
  myBlock1.draw();
  myBlock2.draw();
  myBlock3.draw();
}

class Block {
  constructor() {
    this.x = random(width); //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255), random(255), random(255)); //kleur
  }

  draw() {
    fill(this.blockColor);
    rect(this.x, this.y, this.w, this,h);
  }
}

⬆️


5. Meerdere objecten en arrays

Zodra je meerdere objecten wil gaan aanmaken vanuit één class-beschrijving dan wil je natuurlijk niet voor elk object een aparte variabele moeten maken. Dat is nog wel te doen bij 3 objecten, maar als je er 100 wil aanmaken wordt dat al snel lastig. Om dat probleem op te lossen kan je objecten ook in een array opslaan en met een for()-loop een x-aantal keer een nieuw object op een array-positie plaatsen. Vervolgens kun je ook met een for()-loop van elk object dat in de array staat een of meerdere methods aanroepen.

let blockAmount = 10;
let blockArray = [];

function setup() {
  createCanvas(800, 600);
  //de loop wordt zo vaak herhaald als het aantal in
  // de variabele blokckAmount
  for (let i = 0; i < blockAmount; i++) {
    //op positie 0 t/m 9 wordt een nieuw object
    //geplaatst dat gebaseerd is op de Block-
    //class-omschrijving
    blockArray.push(new Block());
  }
}

function draw() {
  background(200);
  //de loop wordt zo vaak herhaald als het aantal in
  // de variabele blokckAmount
  for (let i = 0; i < blockAmount; i++) {
    //van elk object in de array wordt de method
    //draw() aangeroepen, de rechthoek wordt getekend
    blockArray[i].draw();
  }
}

class Block {
  constructor() {
    this.x = random(width); //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255), random(255), random(255)); //kleur
  }

  draw() {
    fill(this.blockColor);
    rect(this.x, this.y, this.w, this,h);
  }
}

⬆️


6. Eigenschappen meegeven aan een object

Soms is het nodig om vanuit de setup()-functie een of meerdere eigenschappen (arguments) mee te geven aan een object, bijvoorbeeld als je de positie wilt laten afhangen van het aantal objecten dat je maakt. Dat kan door argumenten mee te geven bij het aanmaken van het object. Deze argumenten worden vervolgens in de constructor()-functie in de class binnengehaald.

In de onderstaande code zijn twee dingen aangepast ten opzichte van de code daarboven:

let blockAmount = 10;
let blockArray = [];

function setup() {
  createCanvas(800,600);
  for (let i = 0; i < blockAmount; i++) {
    blockArray[i] = new Block((width / blockAmount) * i);
  }
}

function draw() {
  background(200);
  for (let i = 0; i < blockAmount; i++) {
    blockArray[i].draw();
  }
}

class Block {
  constructor(newX) {
    this.x = newX; //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255),random(255),random(255)); //kleur
  }

  draw() {
    fill(this.blockColor);
    rect(this.x, this.y, this.w, this,h);
  }
}

⬆️


7. Eigenschappen meegeven aan methods

Net als dat je eigenschappen als argument mee kan geven aan een object via de constructor()-method, kan je ook aan de andere methods die je hebt aangemaakt in je class-omschrijving argumenten meegeven. Bijvoorbeeld als je iets dat in de algemene code gebeurt invloed wil laten hebben op een of meerdere objecten die je hebt gemaakt.

In het voorbeeld hieronder is er een argument meegegeven aan de draw()-method zodat het vierkant alleen getekend wordt, als de x-positie van de muis hoger is dan de x-positie van het betreffende object. Daarvoor zijn drie aanpassingen nodig:

let blockAmount = 10;
let blockArray = [];

function setup() {
  createCanvas(800,600);
  for (let i = 0; i < blockAmount; i++) {
    blockArray[i] = new Block((width / blockAmount) * i);
  }
}

function draw() {
  background(200);
  for (let i = 0; i < blockAmount; i++) {
    blockArray[i].draw(mouseX);
  }
}

class Block {
  constructor(newX) {
    this.x = newX; //x-positie
    this.y = random(height); //y-positie
    this.b = random(10, 50); //breedte
    this.h = random(10, 50); //hoogte
    this.blockColor = color(random(255),random(255),random(255)); //kleur
  }

  draw(mousePos) {
      if(mousePos > this.x) {
          fill(this.blockColor);
          rect(this.x, this.y, this.w, this,h);
      }
  }
}

⬆️