# Programmeren in Python/Klassen
## Introductie

OGP (Engels: Object Oriented Programming of OOP) is een programmeerstijl (of paradigma, een wijze van werken) waarbij logische objecten gemaakt worden welke methodes (functies, acties of gebeurtenissen) en eigenschappen (waarden) bevatten. De bedoeling is dat dit leidt tot meer leesbare en herbruikbare code. Conceptueel bestaat een programma uit objecten die aangemaakt worden en met elkaar interacteren.
Indien we een programma schrijven waarin we een aantal voertuigen moeten kunnen beheren, dan kunnen we een auto als een object binnen deze software beschouwen. Elke auto heeft een aantal eigenschappen zoals een kleur, aantal kilometers en een topsnelheid. Maar een auto heeft ook een aantal acties zoals remmen, versnellen en draaien. In plaats van elke auto van een aparte code te voorzien zullen we een klasse Car gebruiken welke deze standaard mogelijkheden zal vastleggen.

## Aanmaken van een klasse

Een voorbeeld van een eenvoudige implementatie van de klasse Car kan er als volgt uitzien:
Python-code: Aanmaken van een klasse
Het keyword class gaat de definitie van een klasse vooraf, dit is gevolgd door de naam van de klasse, 'car' in dit geval. Vervolgens bevat deze klasse twee lidfuncties namelijk brake en accelerate. Merk op dat de eerste parameter van een lidfunctie steeds self is, dit is een verwijzing naar het object zelf. Vervolgens kan de klasse op de volgende manier gebruikt worden:
Python-code: Aanmaken van een klasse
Hier worden twee verschillende instanties (objecten) van de car klasse aangemaakt, vervolgens wordt op het eerste object de methode brake opgeroepen en op de tweede de methode accelerate.

## Attributen

Op dit punt is er op data niveau geen onderscheid mogelijk tussen de twee objecten, dit is omdat er geen private data gekoppeld is aan de objecten. Wanneer er echter attributen (properties) toegevoegd worden kunnen deze gebruikt worden om onderscheid te maken tussen objecten. Men kan een eigenschap (dit valt te beschouwen als een variabele gekoppeld aan het object) als volgt toewijzen en opvragen:
Python-code: Attributen
Wanneer het attribuut echter niet toegewezen is resulteert dit in een fout:
Python-code: Attributen
Juist omwille van deze reden is het een goede vuistregel om toegang tot attributen te krijgen via lidfuncties. Dit zijn de bekende get en set functies om attributen op te vragen en te wijzigen. Wanneer de car uitgebreid wordt met de naam van de eigenaar ziet dit er als volgt uit:
Python-code: Attributen
Merk op dat de naam van het attribuut start met een underscore (_), op deze manier wordt de naam van het attribuut verborgen voor gebruikers.

## Een klasse uitbreiden

Wanneer extra functionaliteit aan een klasse toegevoegd dient te worden, of wanneer men een iets meer specifieke implementatie van een bestaande klasse wenst te gebruiken, dan gaat men vaak gebruik maken van overerving. Dit heeft als extra voordeel dat de bestaande klasse niet gewijzigd zal worden. Wanneer een klasse afgeleid wordt van een bestaande klasse, dan zal deze alle bestaande lidfuncties overerven. In het voorbeeld van de Car klasse kunnen we deze uitbreiden tot een Truck klasse welke mogelijkheden biedt om te laden en te lossen. In code ziet dit er alsvolgt uit:
Python-code: Attributen
Indien nu een truck object aangemaakt wordt zal deze kunnen remmen, versnellen, geladen worden en gelost worden, het is zelfs mogelijk om een dezelfde lidfunctie te overschrijven (overriden), op deze manier kan een lidfunctie een andere functionaliteit implementeren. In dit geval kan het bijvoorbeeld van een klasse dier dat implementeren met een lidfunctie spreek welke het geluid print welke het dier maakt, indien men dan aparte dieren gaat afleiden (b.v. een hond of een kat) kan met de spreek lidfunctie per diersoort aanpassen.

## Speciale lidfuncties

Een constructor is een lidfunctie die opgeroepen wordt wanneer een object aangemaakt wordt, deze wordt typisch gebruikt om de attributen te initialiseren op de juiste standaardwaarden. In Python noemt de constructor __init__, de constructor kan eveneens argumenten krijgen. Het volgende voorbeeld toont de constructor van een car object waar bepaalde eigenschappen als parameter gezet worden:
Python-code: Attributen

## Overerving

Inheritance of overerving betekent dat een specifiek object eigenschappen van een algemeen object overneemt. Zo zijn studenten allemaal personen. Algemene persoonseigenschappen vind je dus ook terug bij studenten, maar zij hebben nog specifieke eigenschappen die niet bij alle personen voorkomen:
Python-code: Overerving