PHP OOP – We extenden onze kennis!

Ik hoop dat je genoten hebt van m’n eerste deel en dat je hier lekker mee hebt kunnen oefenen en experimenteren! Het is heel erg belangrijk dat je alle theorie uit dat eerste deel begrijpt en ook toe kunt passen!
Jan-Jaap heeft ook al het extends keyword gebruikt, dat ga ik in deze tutorial ook weer wat verder uitleggen.

Dus, Wat gaan we doen?

Eigenlijk gaan we weer hetzelfde doen als in het vorige deel, we gaan weer een auto klasse maken. Maar elke auto is natuurlijk anders, dus maken we meerdere klassen. Dit lijkt omslachtig ja, maar dat is waar het extends keyword komt kijken!

Eerst wat theorie.

De definitie van een klasse kennen jullie nu natuurlijk al (anders moet je m’n eerste deel nog maar is lezen). Maar er komt nog een deel bij. Een klasse kan namelijk ook iets zijn dat een uitbreiding is van een andere klasse. Als dit het geval is, dan neemt een klasse alle methods en variabelen van de ouder-klasse over. Vervolgens kun je nieuwe methods toevoegen, variabelen toevoegen, methods veranderen en variabelen veranderen, behalve als er een bescherming op zit.

Een bescherming?

Ja een bescherming! Weet je nog dat we het hadden over private, protected en public? Je weet dat public was om een method of variabele vanuit de instantie te kunnen benaderen, maar wat is nou het verschil tussen private en protected. Een private method of variabele kan alleen worden gebruikt door de klasse waarin hij gedefinieerd is, een protected method of variabele kan ook worden gebruikt door een uitbreiding van de klasse/kinderklasse/extended klasse. Behalve als je echt niet wilt dat iets in een uitbreidingsklasse wordt gebruikt, raad ik je dus aan om altijd protected te gebruiken!

Maak maar een auto dan!

We gaan nu eerst weer de auto klasse terughalen, ik voeg hier ook een maximumsnelheid aan toe, ook heb ik alle echo’s verwijderd, omdat dat niet netjes is:

class Auto
{
public $merk = 'onbekend';
public $kleur = 'onbekend';
public $nummerbord = 'on-be-kend';
protected $snelheid = 0;
protected $maxSnelheid = 150; //sneller dan dit mag de auto niet gaan
protected $lichten = false; //lichten standaard uit

public function __construct($merk, $kleur, $nummerbord)
{
$this->merk = $merk;
$this->kleur = $kleur;
$this->nummerbord = $nummerbord;
$this->lichten = rand(0, 1);
}

public function geefGas($snelheid = 5)
{
$this->snelheid += $snelheid; //Let op dat je hier niet in de war raakt!
}

public function geefMinderGas($snelheid = 5)
{
$this->snelheid -= $snelheid; //natuurlijk kun je dit ook bereiken met de vorige method, bij een snelheid van -5 ;)
}

public function kijkOpSnelheidsmeter()
{
return $this->snelheid;
}

public function handrem()
{
$snelheid = $this->snelheid; //de oude snelheid bewaren
$this->snelheid = 0;

$this->botsing($snelheid); //roep een andere method aan
}

public function switchLichten()
{
$this->lichten = !$this->lichten;

return $this->lichten;
}

private function botsing($beginsnelheid)
{
if(!rand(0, 9) || $beginsnelheid > 100 || $beginsnelheid < -100)
{
return true;
}
else
{
return false;
}
}
}
?>

Nu wil ik een Ferrari die harder kan rijden en sneller optrekt, een Audi die minder snel kan rijden en geen lichten heeft en een bmw zonder handrem en met een kapotte snelheidsmeter. Dit kunnen we op twee manieren berijken:
1. We maken voor elke auto een andere klasse, nadeel: kost erg veel ruimte! Voordeel: dat begrijpen we!
2. We maken extend klassen van de Auto klasse waarmee we bepaalde dingen veranderen, nadeel: begrijpen we nog niet! Voordeel: lekker makkelijk/klein
Natuurlijk kiezen we voor optie 2, we zijn lui! En geen zorgen, ik leg het wel uit!

Aan de slag dan maar!

Juist, we beginnen met de makkelijkste, de Ferrari! Eerst maken we de klasse en zeggen we dat de klasse Auto moet naapen:
class Ferrari extends Auto
{
}

Eerst vertellen we dat hij harder mag rijden:
class Ferrari extends Auto
{
protected $maxSnelheid = 355;
}

Nu schrijven we de geefGas method opnieuw:

class Ferrari extends Auto
{
protected $maxSnelheid = 355;

public function geefGas($snelheid = 10) //door de 10 trekt de ferrari twee keer zo snel op!
{
$this->snelheid += $snelheid; //Let op dat je hier niet in de war raakt!
if($this->snelheid > $this->maxSnelheid)
{
$this->snelheid = $this->maxSnelheid;
}
}
}

En dat is alles wat je nodig hebt om een nieuwe klasse te schrijven, alle andere methods en variabelen werken namelijk ook nogsteeds! Nu gaan we hetzelfde doen, maar dan voor de Audi!

class Audi extends Auto
{
protected $maxSnelheid = 76;

public function __construct($merk, $kleur, $nummerbord)
{
$this->merk = $merk;
$this->kleur = $kleur;
$this->nummerbord = $nummerbord;
//we willen niet dat hier de lichten aan kunnen gaan!
//$this->lichten = rand(0, 1);
}

public function switchLichten()
{
return false;
}
}

En voor de bmw:

class BMW extends Auto
{
public function handrem(){} //geen handrem meer!

public function kijkOpSnelheidsmeter()
{
return $this->snelheid + rand(-10, 10);
}
}

Zoals je ziet kost het dus helemaal geen moeite om 3 verschillende auto’s maken!

Laat maar zien hoe makkelijk je dit gebruikt dan!

Oke, hoe je het gebruikt is eigenlijk gewoon hetzelfde als met een normale klasse! Ik zal jullie ff een voorbeeldcode geven om het uit te kunnen testen ;) Bekijk die hier, de uiteindelijke versie van de klassen is hier te vinden.
Maar, waarvoor kan ik dit dan gebruiken!
Het kunnen extenden van klasses is erg handig bij het gebruik maken van Exceptions. Ook is het erg handig als je een systeem maakt dat kan worden gedownload/gekocht door iedereen! Dan kun je een db klasse maken die alle standaard dingen met de db afhandeld, een mysql klasse maken die db extend en alle dingen doet waarvoor het type nodig is. En dan zo ook een pgsql klasse maken enz.

Tja, dat was het..

Ik hoop dat je het nu begrijpt en kunt toepassen. Snap je iets niet of wil je nog iets anders weten, moet ik nog iets anders behandelen? Vraag het in de comments of op het forum! En onthoud: nog een keer lezen en dingen uitproberen is gratis!

Tags: , , , ,

2 Responses to “PHP OOP – We extenden onze kennis!”

  1. Jan Jaap says:

    Ik wou eigelijk nog één toevoeging maken op het artikel en dat is het final keyword.

    Wanneer jij als auteur van een class wilt dat een bepaalde functie en/of variabele niet vervangen/overschreven kan worden, kun je dit keyword gebruiken.

    Een functie ziet er dan bijvoorbeeld als volgt uit:
    final public function do_stuff() {}
    Wanneer je een class dan extend, kun je deze functie niet vervangen.

  2. Leroy says:

    Mooie toevoeging ;)
    Hier had ik helemaal niet aan gedacht :P