PHP Tutorial.nl

Word een PHP expert!!!

Home » Object Georiënteerd Programmeren

Object georiënteerd programmeren: De basis uitgelegd

Nu we weten wat een class, abstracte class en interface zijn is het tijd om het principe van Object Georiënteerd Programmeren (OOP) te gaan leren. OOP gaat uit van objecten. Alles in de code is in theorie een object. 

Wat is object georiënteerd programmeren (OOP)?

Object Georiënteerd Programmeren (OOP) is een programmeerparadigma dat is gebaseerd op het concept van “objecten”. Objecten zijn weer instanties van classes, die zowel data (eigenschappen) als functies (methoden) bevatten. Dit maakt het mogelijk om code te structureren op een manier die de echte wereld nabootst, waardoor het makkelijker wordt om complexe systemen te bouwen en te onderhouden.

Belangrijke concepten in OOP

  • Klassen en Objecten: Een klasse definieert een blueprint voor objecten.
  • Encapsulatie: Het verbergen van interne objectdetails.
  • Overerving: Het creëren van nieuwe klassen gebaseerd op bestaande klassen.
  • Polymorfisme: Het gebruik van één interface voor verschillende onderliggende vormen (types).

Klassen en objecten

Klassen zijn blauwdrukken voor objecten. Ze definiëren eigenschappen en methoden die de objecten zullen hebben. Een object is een instantie van een klasse.

<?php
class Auto {
    public $merk;
    public $model;

    public function __construct($merk, $model) {
        $this->merk = $merk;
        $this->model = $model;
    }

    public function beschrijving() {
        return "Deze auto is een $this->merk $this->model.";
    }
}

$auto = new Auto("Toyota", "Corolla");
echo $auto->beschrijving(); // Output: Deze auto is een Toyota Corolla.
?>

Encapsulatie

Encapsulatie houdt in dat de interne details van een object worden verborgen. Dit gebeurt door eigenschappen en methoden als private of protected te markeren, zodat ze alleen binnen de klasse of afgeleide klassen toegankelijk zijn.

<?php
class Gebruiker {
    private $naam;

    public function __construct($naam) {
        $this->naam = $naam;
    }

    public function getNaam() {
        return $this->naam;
    }
}

$user = new Gebruiker("Alice");
echo $user->getNaam(); // Output: Alice
?>

Overerving

Overerving maakt het mogelijk om een nieuwe klasse te maken die eigenschappen en methoden van een bestaande klasse overneemt. Dit bevordert codehergebruik en maakt het eenvoudiger om aanpassingen door te voeren.

<?php
class Dier {
    public function maakGeluid() {
        echo "Geluid!";
    }
}

class Hond extends Dier {
    public function maakGeluid() {
        echo "Woef!";
    }
}

$hond = new Hond();
$hond->maakGeluid(); // Output: Woef!
?>

Polymorfisme

Polymorfisme betekent dat een enkele interface voor verschillende datatypes kan worden gebruikt. Het maakt het mogelijk om dezelfde methode op verschillende objecten aan te roepen, en elk object kan een eigen implementatie van die methode hebben.

<?php
class Dier {
    public function maakGeluid() {
        echo "Algemeen geluid";
    }
}

class Hond extends Dier {
    public function maakGeluid() {
        echo "Woef!";
    }
}

class Kat extends Dier {
    public function maakGeluid() {
        echo "Miauw!";
    }
}

function laatDierGeluidMaken(Dier $dier) {
    $dier->maakGeluid();
}

$hond = new Hond();
$kat = new Kat();

laatDierGeluidMaken($hond); // Output: Woef!
laatDierGeluidMaken($kat);  // Output: Miauw!
?>

Wat is eigenlijk een object?

 Onze wereld bestaat uit objecten. Alles om ons heen is een object en/of bestaat uit meerdere objecten. Voorbeelden van objecten zijn: een glas, een tafel, de televisie, enzovoort. In theorie heeft elk object slechts één verantwoordelijkheid (single responsibility). Het kan in theorie niet meer dan één ding.

Sommige objecten bestaan uit meerdere andere objecten. Neem bijvoorbeeld een fiets. Een fiets is een object, maar heeft bijvoorbeeld twee wielen. Deze wielen zijn ook objecten.  Daarnaast heeft een fiets onder andere een ketting, een paar tandwielen, verlichting, stuur, trappers en een zadel. Dit zijn allemaal objecten.

De fiets als object is eigenlijk een verzameling van losse objecten. We noemen dit een compositie. In programmeer ‘jargon’ een composite.

Heeft de fiets dan meerdere verantwoordelijkheden? Dat de fiets uit meerdere losse objecten bestaat betekent niet dat hij meerdere verantwoordelijkheden heeft. Een fiets is een vervoersmiddel en heeft als verantwoordelijkheid: vervoeren. 

Herbruikbaarheid van objecten

Als code goed is opgezet, dan zijn objecten opnieuw te gebruiken (reusable).  We schrijven de definities van objecten als classes en instantiëren deze dan. Neem nu een wiel, als object in de echte wereld is deze op bijna elk vervoersmiddel terug te vinden: fietsen, motorfietsen, auto’s, vliegtuigen, etc. 

In de meeste gevallen is alleen de diameter verschillend. Dit is dus een bepaalde eigenschap.  Als we een definitie van een class maken voor wiel, dan zou deze er als volgt uitzien:

<?php
class Wiel {   
   protected $diameter;

   public function __construct( $diameter ) {
      $this->diameter = $diameter;
   }
}

Nu kunnen we allemaal logica gaan toevoegen die horen bij een wiel. Hierbij is te denken aan het roteren. Wellicht willen we nog een methode toevoegen die op basis van parameters aangeeft hoeveel omwentelingen we maken en dus hoe snel we gaan. Voor nu laat ik dit even buiten beschouwing.

De herbruikheid en de kracht van objecten zit in het goed uitdenken van elk concept. Een fietszadel is natuurlijk een stoel en een fiets als vervoersmiddel heeft slechts 1 stoel. Een auto heeft bijvoorbeeld ‘5’ stoelen (als we de achterbank als 3 zitplaatsen, dus drie ‘stoelen’ zien).

Dependencies

In objectgeoriënteerd programmeren (OOP) is een dependency een object waarvan een ander object afhankelijk is om zijn taak uit te voeren. Dependencies kunnen een directe invloed hebben op de functionaliteit en flexibiliteit van je code. Het beheren van dependencies is daarom essentieel voor het maken van onderhoudbare en uitbreidbare applicaties.

Dependency Injection

Dependency Injection is een design pattern dat helpt bij het beheren van dependencies. Het houdt in dat de afhankelijkheden van een object van buitenaf worden geleverd, in plaats van dat het object ze zelf creëert. Dit bevordert loskoppeling en maakt het makkelijker om onderdelen van je applicatie te testen en te vervangen.

<?php
class Database {
    public function connect() {
        echo "Database verbonden.";
    }
}

class GebruikersService {
    private $database;

    public function __construct(Database $database) {
        $this->database = $database;
    }

    public function gebruikService() {
        $this->database->connect();
        echo "Service gebruikt.";
    }
}

$database = new Database();
$service = new GebruikersService($database);
$service->gebruikService();
// Output: Database verbonden. Service gebruikt.
?>

In dit voorbeeld wordt de Database dependency geïnjecteerd in de GebruikersService klasse via de constructor. Dit maakt de GebruikersService klasse flexibeler en eenvoudiger te testen, omdat je gemakkelijk een mock Database kunt injecteren tijdens het testen.

Dependency Injection helpt, zoals je ziet, bij het creëren van flexibele en onderhoudbare objectgeoriënteerde code door het bevorderen van loskoppeling tussen objecten.