Logo des digitalen Schulbuchs inf-schule.de. Schriftzug in Zustandsübergangsdiagramm eines endlichen Automaten.

Zugriff auf die Attribute

Experimente mit Ampel-Objekten

Wir betrachten noch einmal eine Ampel mit den üblichen Ampelphasen.

Ampelzustände

Es gibt eine Vielzahl von Möglichkeiten, eine Klasse Ampel zur Simulation einer solchen Ampel zu konzipieren. Hier eine - neben den bisher betrachteten - weitere Möglichkeit:

class Ampel(object):
    def __init__(self):
        self.zustand = 'rot'
        self.lampeRot = None
        self.lampeGelb = None
        self.lampeGruen = None
        self.aktualisiereLampen()

    def getLampen(self):
        return (self.lampeRot, self.lampeGelb, self.lampeGruen)

    def schalten(self):
        if self.zustand == 'rot':
            self.zustand = 'rotgelb'
        elif self.zustand == 'rotgelb':
            self.zustand = 'gruen'
        elif self.zustand == 'gruen':
            self.zustand = 'gelb'
        elif self.zustand == 'gelb':
            self.zustand = 'rot'
        self.aktualisiereLampen()

    def aktualisiereLampen(self):
        if self.zustand == 'rot':
            self.lampeRot = True
            self.lampeGelb = False
            self.lampeGruen = False
        elif self.zustand == 'rotgelb':
            self.lampeRot = True
            self.lampeGelb = True
            self.lampeGruen = False
        elif self.zustand == 'gruen':
            self.lampeRot = False
            self.lampeGelb = False
            self.lampeGruen = True
        elif self.zustand == 'gelb':
            self.lampeRot = False
            self.lampeGelb = True
            self.lampeGruen = False

Ein Benutzer der Klasse Ampel führt den folgenden Python-Dialog:

>>> a = Ampel()
>>> a.zustand
'rot'
>>> a.getLampen()
(True, False, False)
>>> a.schalten()
>>> a.zustand
'rotgelb'
>>> a.getLampen()
(True, True, False)
>>> a.zustand = 'gruen'
>>> a.zustand
'gruen'
>>> a.getLampen()
(True, True, False)

Aufgabe 1

Führe selbst diesen Dialog aus. Warum ist dieser Dialog nicht im Sinne des Ampelsystems? Woran liegt das?

Kapselung der Daten

Objekte nutzen Attribute, um die Daten, für die sie zuständig sind, zu verwalten. Ein leichtfertiger Zugriff auf die Attribute kann leicht zu unerwünschten Objektzuständen führen. Es ist daher eine gute Strategie, solche Zugriffe zu unterlassen oder sogar zu verbieten.

Wir setzen diese Strategie im Folgenden um, indem wir nicht mehr direkt auf Objektattribute zugreifen. Es sollen also keine direkten Zugriffe der Form objekt.attribut mehr erfolgen.

Ein Zugriff auf die Daten eines Objekts soll ab jetzt nur noch mit Hilfe geeigneter Methoden durchgeführt werden. Damit das möglich wird, erweitern wir zuerst die Klassendeklaration.

class Ampel(object):
    def __init__(self):
        self.zustand = 'rot'
        self.lampeRot = None
        self.lampeGelb = None
        self.lampeGruen = None
        self.aktualisiereLampen()

    def setZustand(self, z):
        self.zustand = z
        self.aktualisiereLampen()

    def getZustand(self):
        return self.zustand

    def getLampen(self):
        return (self.lampeRot, self.lampeGelb, self.lampeGruen)

    def schalten(self):
        if self.zustand == 'rot':
            self.zustand = 'rotgelb'
        elif self.zustand == 'rotgelb':
            self.zustand = 'gruen'
        elif self.zustand == 'gruen':
            self.zustand = 'gelb'
        elif self.zustand == 'gelb':
            self.zustand = 'rot'
        self.aktualisiereLampen()

    def aktualisiereLampen(self):
        if self.zustand == 'rot':
            self.lampeRot = True
            self.lampeGelb = False
            self.lampeGruen = False
        elif self.zustand == 'rotgelb':
            self.lampeRot = True
            self.lampeGelb = True
            self.lampeGruen = False
        elif self.zustand == 'gruen':
            self.lampeRot = False
            self.lampeGelb = False
            self.lampeGruen = True
        elif self.zustand == 'gelb':
            self.lampeRot = False
            self.lampeGelb = True
            self.lampeGruen = False

Mit den hinzugefügten Methoden lässt sich der oben gezeigte Vorgang jetzt so simulieren:

>>> a = Ampel()
>>> a.getZustand()
'rot'
>>> a.getLampen()
(True, False, False)
>>> a.schalten()
>>> a.getZustand()
'rotgelb'
>>> a.getLampen()
(True, True, False)
>>> a.setZustand('gruen')
>>> a.getZustand()
'gruen'
>>> a.getLampen()
(False, False, True)

Aufgabe 2

(a) Für welche Daten ist in diesem Beispiel das Ampel-Objekt zuständig?

(b) Überzeuge dich, dass im Shell-Mitschnitt kein direkter Zugriff auf die Daten des Ampel-Objekts erfolgt. Auf welche Weise kann man sich dennoch die Daten verschaffen?

(c) Warum ist es sinnvoll, dass Benutzer einer Klasse nur die Methoden der Klasse verwenden?

X

Fehler melden

X

Suche