Programmeren in Python

Programmeren in Python

Dictaat Object-georiënteerd programmeren met klassen en instanties

In dit dictaat worden de volgende nieuwe Python instructies en taalconstructies geïntroduceerd (klik op de instructie om de definitie in een nieuw tabblad op de officiële Python taalgids te bekijken):

  • class Definitie van een klasse

Object georiënteerd programmeren maakt het mogelijk om variabelen en functies van te voren te definiëren in een klasse en deze te gebruiken in één of meerdere instanties (objecten). We noemen dit ook wel het instantiëren van een klasse: we gebruiken een klassedefinitie om een object mee aan te maken dat op dat moment alle variabelen en functies heeft die in de klasse zijn gedefinieerd.

Twee klassen en een van een klasse geïnstantieerd object (illustratie Testconsultancy Groep)

Onderwerpen in dit dictaat:

  • Conceptueel overzicht van object georiënteerd programmeren
  • Definitie van klassen en zelfreferentie met self
  • Klassemethoden: de functies van een klasse
  • __init__ en __str__ methoden
  • Instanties van een klasse
  • Klassevariabelen, instantievariabelen en encapsulatie
  • Dynamisch toevoegen van attributen aan enkele en alle instanties
  • Polymorfisme en overerving
  • Gebruik van de ingebouwde methodes

Klassedefinitie

Een klassedefinitie fungeert als een blauwdruk voor objecten (illustratie Testconsultancy Groep)

Een klasse wordt ook wel ‘object typering’ of ‘blauwdruk’ genoemd. Een klasse wordt in Python gedefinieerd met het woord class, gevolgd door de naam van de te definiëren klasse. Het codeblok dat hieronder valt, is de klassedefinitie. Binnen een klasse kunnen op de gebruikelijke wijze functies met def worden gedefinieerd. Deze zijn pas beschikbaar als een object van de klasse is geïnstantieerd. Twee speciale functies zijn __init__ en __str__. De eerste wordt aangeroepen bij de instantiëring en de tweede wordt aangeroepen als een object wordt geprint met print(mijn_object).

Klassen worden in Python doorgaans met een hoofdletter geschreven, zoals class Doos. In Python bestaat het self keyword, waarmee naar de eigen klasse wordt verwezen. self moet in iedere klassefunctie als eerste parameter worden gedefinieerd, maar wordt bij het aanroepen niet genoemd: def geefMeEen(self, cijfer) in de klassedefinitie wordt in het object aangeroepen als geefMeEen(10), dus zonder de eerste parameter self. Instantievariabelen worden binnen de instantie benaderd met self.laatsteCijfer, buiten de instantie met instantienaam.laatsteCijfer.

Functies in een klasse worden aangeroepen met instantienaam.klassefunctie(). Een klassefunctie wordt ook wel klassemethode genoemd.

class Doos:
    def __init__(self, breedte, hoogte, diepte):
        self.breedte = breedte
        self.hoogte = hoogte
        self.diepte = diepte
        self.label = None
        self.isOpen = True

    def __str__(self):
        if self.label is not None:
            return "Het label op deze doos zegt '" + self.label + "'"
        else:
            return "Er zit geen label op deze doos"

    def plaklabel(self, tekst):
        self.label = tekst

    def sluit(self, doeDicht):
        if doeDicht:
            self.isOpen = False
        else:
            self.isOpen = True

In het voorbeeld wordt de klasse Doos gedefinieerd. Een doos heeft een breedte, hoogte en diepte en kan een label bevatten. Een doos is open of gesloten en de status hiervan wordt bijgehouden met isOpen. De beginwaarden van de doos worden in de functie __init__ geïnitialiseerd. Deze functie wordt door Python aangeroepen als een object van deze klasse wordt geïnstantieerd. Er wordt naar de eigen variabelen van de klasse gerefereerd door ze vooraf te laten gaan door self. De functie __str__ dient een string op te leveren en wordt aangeroepen als een object naar een string moet worden omgezet, bijvoorbeeld in een print(object). Verder zie je in de klassedefinitie twee functies plaklabel en sluit, die gebruik maken van de klassevariabelen tekst en isOpen.

Alle eigenschappen (variabelen en methoden) van een klasse kunnen middels de objectnaam.eigenschap syntax worden aangeroepen: verhuisdoos.sluit(True), maar ook verhuisdoos.breedte = 10. Het is conventie om eigenschappen die met _ beginnen niet van buiten het object aan te roepen en alleen via methoden beschikbaar te maken. Eigenschappen die beginnen met __ echter worden ‘verborgen’ achter _klasse (ze worden hernoemd door Python) en worden op die manier beschermd tegen gebruik van buiten het object.

Objectinstantiëring

Een object wordt geinstantiëerd van een klasse (illustratie Testconsultancy Groep)

Een object is een klasse-instantie en wordt aangemaakt met mijn_object = Klasse(beginwaarden). De __init__ methode die in de klasse is gedefinieerd wordt nu aangeroepen met de beginwaarden.

verhuisdoos = Doos(30, 30, 30)
verhuisdoos.sluit(True)
print(verhuisdoos)
verhuisdoos.plaklabel("Huiskamer")
print(verhuisdoos)

verhuisdozen = []
verhuisdozen.append(verhuisdoos)

In het voorbeeld wordt een object verhuisdoos geinstantieerd van de klasse Doos met als beginwaarden 30, 30, 30. Vervolgens wordt de klassemethode sluit() aangeroepen om de doos te sluiten. Door het object te printen wordt de interne klassefunctie __str__ aangeroepen. Je kunt objecten in een lijst (of ieder andere Python verzameling) gebruiken. In het voorbeeld wordt een lijst verhuisdozen gemaakt en wordt het object verhuisdoos hieraan toegevoegd. Je zou de verhuisdoos nu adresseren met bijvoorbeeld print(verhuisdoos[0]) of verhuisdoos[0].sluit(False).

Overerving

Bij het beschrijven van een klasse kan een andere klasse worden opgegeven waarvan de eigenschappen worden overgenomen, zoals een doos die de eigenschappen van een kubus overneemt. Gebruik hiervoor class Doos(Kubus): Met super() kan naar een bovenliggende klasse worden verwezen als van eigenschappen van de bovenliggende klasse gebruik moet worden gemaakt. Een bovenliggende klasse noemen we superklasse, een onderliggende (afgeleide) klasse noemen we een subklasse. De allerbovenste klasse die zelf niet meer ergens van is afgeleid heet ook wel de basisklasse (base class).

class Kubus:
    def __init__(self, breedte, hoogte, diepte):
        self.breedte = breedte
        self.hoogte = hoogte
        self.diepte = diepte

    def __str__(self):
        return "Dit is een kubus"


class Doos(Kubus):
    def __init__(self, breedte, hoogte, diepte):
        super().__init__(breedte, hoogte, diepte)
        self.label = None
        self.isOpen = True

    def __str__(self):
        if self.label is not None:
            return "Het label op deze doos zegt '" + self.label + "'"
        else:
            return "Er zit geen label op deze doos"

    def plaklabel(self, tekst):
        self.label = tekst

    def sluit(self, doeDicht):
        if doeDicht:
            self.isOpen = False
        else:
            self.isOpen = True

Samenvatting klassen en instanties

Hieronder de in dit dictaat behandelde onderwerpen:

  • ŸInstantiëren (instantiating): een nieuwe variabele van een bepaalde klasse wordt aangemaakt
  • ŸMethoden (methods): functies die in een klasse zijn gedefinieerd
  • ŸInsluiten (ecapsulating): variabelen die door de klasse afgeschermd zijn (en via een methode/functie worden ontsloten)
  • ŸPolymorfisme (polymorfism): een functie of variabele met zelfde naam heeft/krijgt in een object een nieuwe werking
  • ŸZelfreferentie (selfreference): de manier waarop methoden van de eigen klassevariabelen en klassefuncties gebruik maken
  • ŸOvererving (inheritance): een klasse wordt gebaseerd op een andere klasse en erft dan de eigenschappen van die klasse

Geef een antwoord