Konzepte objektorientierter Programmierung

110
Konzepte objektorientierter Programmierung Klaus Becker 2009

description

Konzepte objektorientierter Programmierung. Klaus Becker 2009. Objektorientierung. " Objektorientierung ist die derzeitige Antwort auf die gestiegene Komplexität der Softwareentwicklung." Oestereich: Objektorientierte Software-Entwicklung. Teil 1. Objekte. S. - PowerPoint PPT Presentation

Transcript of Konzepte objektorientierter Programmierung

Page 1: Konzepte objektorientierter Programmierung

Konzepte objektorientierter Programmierung

Klaus Becker

2009

Page 2: Konzepte objektorientierter Programmierung

2 Objektorientierung

"Objektorientierung ist die derzeitige Antwort

auf die gestiegene Komplexität der

Softwareentwicklung."Oestereich: Objektorientierte Software-

Entwicklung

Page 3: Konzepte objektorientierter Programmierung

3 Teil 1

Objekte

Page 4: Konzepte objektorientierter Programmierung

4 Verwaltung von Bankkonten

Ziel ist es, ein System zur Verwaltung von Bankkonten zu entwickeln. Dieses System soll recht einfach gestaltet werden, um es leicht durchschaubar zu halten. Aus diesem Grund werden wir auf viele Aspekte eines realen Bankkontenverwaltungssystem verzichten.

SKonto-Nr.234126 Freunde des Burggymnasiums Kontoauszug

Blatt 342

Datum Erläuterung Betrag

01.07.2009 Miete der Fruchthalle - Sommerkonzert 450.00 -

08.07.2009 Spende eines ehemaligen Schülers 1000.00 +

10.07.2009 Zuschuss zum Whiteboard 800.00 -

Kontostand in EUR, 11.07.2009 2130.00 +

Page 5: Konzepte objektorientierter Programmierung

5 Verwaltung von Bankkonten

Wesentliche zu verwaltende Daten erkennt man auf einem Kontoauszug.

SKonto-Nr.234126 Freunde des Burggymnasiums Kontoauszug

Blatt 342

Datum Erläuterung Betrag

01.07.2009 Miete der Fruchthalle - Sommerkonzert 450.00 -

08.07.2009 Spende eines ehemaligen Schülers 1000.00 +

10.07.2009 Zuschuss zum Whiteboard 800.00 -

Kontostand in EUR, 11.07.2009 2130.00 + Kontostand

Kontonummer

Kontoinhaber

auszahlen

einzahlen

auszahlen

Ein Bankkonto hat eine bestimmte Kontonummer (und einen Kontoinhaber - von dem wir vorerst einmal absehen). Ein Bankkonto hat zudem einen bestimmten Stand - das ist der Geldbetrag, der aktuell auf dem Konto verfügbar ist. Von einem Bankkonto kann man Geldbeträge auszahlen, man kann aber Geldbeträge auf ein Konto einzahlen.

Page 6: Konzepte objektorientierter Programmierung

6

Objektorientierter Modellierungsansatz

So wie die zu verwaltende Welt aus Objekten - hier Konten - besteht, so soll das Verwaltungssystem aus Softwareobjekten aufgebaut werden.

SKonto-Nr.234126 Freunde des Burggymnasiums Kontoauszug

Blatt 342

Datum Erläuterung Betrag

01.07.2009 Miete der Fruchthalle - Sommerkonzert 450.00 -

08.07.2009 Spende eines ehemaligen Schülers 1000.00 +

10.07.2009 Zuschuss zum Whiteboard 800.00 -

Kontostand in EUR, 11.07.2009 2130.00 +

Softwareobjekt

Page 7: Konzepte objektorientierter Programmierung

7 Softwareobjekt in Aktion

>>> konto = Konto(234126)>>> konto.nr234126>>> konto.stand0>>> konto.stand = 2380.0>>> konto.stand2380.0>>> konto.auszahlen(450.0)>>> konto.stand1930.0>>> konto.einzahlen(1000.0)>>> konto.stand2930.0>>> konto.auszahlen(800.0)>>> konto.stand2130.0

Wenn man das Programm konto.py ausführt, dann lässt sich folgender Python-Dialog führen. Probiere das einmal aus.

Page 8: Konzepte objektorientierter Programmierung

8 Objekte

Ein Objekt ist eine Einheit, die Daten mit Hilfe von Attributen verwalten und Operationen zur Verarbeitung der verwalteten Daten mit Hilfe von Methoden ausführen kann.

Attribute sind - an Objekte gebundene - Variablen zur Verwaltung von Daten. Diese entsprechen in der Regel den Eigenschaften der betreffenden Objekte.

Methoden sind - an Objekte gebundene - Prozeduren oder Funktionen zur Verarbeitung von Daten. Diese Methoden werden ausgeführt, wenn das betreffende Objekt Operationen ausführt.

Ein Objekt befindet sich stets in einem bestimmten Zustand. Der aktuelle Objektzustand wird durch die aktuellen Werte der Attribute festgelegt.

Objekt

Attribute - Attributwerte

Ausführung einer Methode

Objektdiagramm

Page 9: Konzepte objektorientierter Programmierung

9 Objekte

Objekt

Attribute - Attributwerte

Ausführung einer Methode

Zugriff auf Attribute:

konto.stand = 2380.0

objekt.attribut

Aktivierung von Methoden:

konto.einzahlen(1000.0)

objekt.methode

Page 10: Konzepte objektorientierter Programmierung

10 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.1.4)

Lade die Datei wuerfel.txt herunter (benenne sie in wuerfel.py um) und führe einen Python-Dialog analog zum folgenden:

>>> w = Wuerfel()>>> w.augen1>>> w.werfen()>>> w.augen6

(a) Was leistet das Attribut augen des Objekts w, was die Methode werfen()?

(b) Beschreibe den gezeigten Ablauf mit Hilfe von Objektdiagrammen.

Page 11: Konzepte objektorientierter Programmierung

11 Teil 2

Klassen

Page 12: Konzepte objektorientierter Programmierung

12 Ein Bauplan für Konto-Objekte

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): # ...

Aufgabe 1:Analysiere diese Klassendeklaration und ergänze den fehlenden Teil # ....Überprüfen kannst du deinen Lösungsvorschlag, indem du die Klassendeklaration unter einem geeigneten Namen (z. B. konto.py) abspeicherst und ausführst. Wenn du alles richtig gemacht hast, dann sollte z. B. der oben gezeigte Python-Dialog möglich sein.

>>> k1 = Konto(5)>>> k1.nr5>>> k1.stand0>>> k1.einzahlen(100.0)>>> k1.stand100.0

Page 13: Konzepte objektorientierter Programmierung

13 Ein Bauplan für Konto-Objekte

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): # ...

Aufgabe 2:Versuche auch einmal, mehrere Konto-Objekte zu erzeugen.Überweise mit passenden Methoden 500.0 (Euro) vom Konto mit der Kontonummer 5 auf das Konto mit der Kontonummer 8.

>>> k1 = Konto(5)>>> k1.einzahlen(1000.0)>>> k2 = Konto(8)>>> ...

Page 14: Konzepte objektorientierter Programmierung

14 Klassen

Eine Klasse ist ein Bauplan für Objekte. Dieser Bauplan legt genau fest, welche Attribute die zu konstruierenden Objekte haben sollen und welche Methoden sie ausführen können sollen.

Objektdiagramm

Ein Objekt (als Exemplar einer Klasse) ist eine Einheit, die nach dem Bauplan der zugeordneten Klasse erzeugt wurde. Ein Objekt verfügt somit über die Attribute, die in der Klasse festgelegt sind. Diesen Attributen können - im Unterschied zur Klasse - Attributwerte zugewiesen werden. Ein Objekt kann zudem sämtliche Methoden der Klasse ausführen. Ausgenommen bleibt hier nur die Methode, deren Name mit dem Klassennamen übereinstimmt (s. u.). Objekte können mit Namen versehen werden, über die sie dann gezielt angesprochen werden können.

Klassendiagramm

Page 15: Konzepte objektorientierter Programmierung

15 Konstruktor / Destruktor

Zur Erzeugung von Objekten verfügt eine Klasse über eine spezielle Methode, die sogenannte Konstruktormethode.

Zur Vernichtung von Objekten verfügt eine Klasse über eine sogenannte Destruktormethode.

Ein Software-Objekt hat - wie viele Objekte der realen Welt - eine bestimmte Lebensdauer. Es muss erzeugt werden, bevor es in Aktion treten kann, und kann auch wieder vernichtet werden.

In einem Klassendiagramm wird eine Konstruktormethode dadurch gekennzeichnet, dass sie denselben Namen wie die Klasse selbst trägt. Oft wird diese spezielle Methode in Klassendiagrammen aber auch weggelassen. Beachte, dass eine Konstruktormethoden keine Methode ist, die ein Objekt ausführen kann.

Destruktormethoden werden in der Regel in Klassendiagrammen weggelassen.

Konstruktor

Page 16: Konzepte objektorientierter Programmierung

16 Klassendeklaration in Python

Klassenname

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

DoppelpunktEinrückung

Schlüsselwort

Oberklasse

AttributeAttribute

Konstruktor

Methode

Methode

Referenz auf Objekt

Page 17: Konzepte objektorientierter Programmierung

17 Objekterzeugung in Python

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

>>> k1 = Konto(5)>>> k2 = Konto(8)>>> k1.nr5>>> k1.stand0>>> k2.nr8>>> k2.stand0>>> k1.__dict__{'nr': 5, 'stand': 0}>>> k2.__dict__{'nr': 8, 'stand': 0}

>>> k = Konto(5)>>> k.stand0.0>>> del k>>> k.standTraceback (most recent call last): File ...NameError: name 'k' is not defined>>>

Klassendeklaration

Erzeugung eines Objekts

Vernichtung eines Objekts

Inspektion eines Objekts

Page 18: Konzepte objektorientierter Programmierung

18 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.2.5)

Gegeben ist eine Implementierung der Klasse Wuerfel():

from random import randint

class Wuerfel(object): def __init__(self): self.augen = 1

def werfen(self): self.augen = randint(1, 6)

Erzeuge drei Objekte der Klasse Wuerfel und würfele hiermit solange, bis mindestens einer der Würfel eine 6 liefert.

Page 19: Konzepte objektorientierter Programmierung

19 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.2.5)

Gegeben ist das folgende Klassendiagramm zur Klasse Bruch:

Was soll mit einem Objekt der Klasse Bruch beschrieben werden? Entwickle eine geeignete Implementierung und teste sie mit einem Python-Dialog.

Page 20: Konzepte objektorientierter Programmierung

20 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.2.5)

Wenn man modulo einer vorgegebenen Zahl (man nennt sie auch Modul) zählt, dann bildet man jeweils den Rest bei der Division durch die vorgegebene Zahl.

Betrachte als Beispiel die vorgegebene Zahl (Modul) 5. Wenn man modulo 5 zählt, dann geht das so: 0 modulo 5, 1 modulo 5, 2 modulo 5, 3 modulo 5, 4 modulo 5, 5 modulo 5, 6 modulo 5, ... Berechnet man jeweils die Reste, dann ergibt das folgende die Zahlenfolge 0, 1, 2, 3, 4, 0, 1, ... .

Wenn man modulo einer vorgegebenen Zahl n zählt, dann ergibt das also die Zahlenfolge 0, 1, ..., (n-1), 0, 1, ....

Konzipiere eine Klasse ModuloZaehler (mit einem Klassendiagramm), die Python-Dialoge wie den folgenden ermöglicht. Implementiere die Klasse und teste sie mit geeigneten Python-Dialogen.

>>> z = ModuloZaehler(3)>>> z.modul3>>> z.stand0>>> z.weiterzaehlen()>>> z.stand1>>> z.weiterzaehlen()>>> z.stand2>>> z.weiterzaehlen()>>> z.stand0>>> z.zurueckzaehlen()>>> z.stand2>>> z.nullsetzen()>>> z.stand0

Page 21: Konzepte objektorientierter Programmierung

21 Übungen

Aufgabe 5 (siehe www.inf-schule.de 1.12.2.5)

Die Klasse Schlange kann man verwenden, um Warteschlangen zu simulieren. Erläutere, was die Methoden der Klasse Schlange bewirken. Verdeutliche deine Erläuterungen jeweils mit einem geeigneten Python-Protokoll.

class Schlange(object): def __init__(self): self.liste = []

def istLeer(self): if self.liste == []: return True else: return False

def mitLetztem(self, element): self.liste = self.liste + [element]

def ohneErstes(self): if not self.istLeer(): self.liste = self.liste[1:]...

... def anzahlElemente(self): return len(self.liste)

def getSchlange(self): return self.liste

def setSchlange(self, liste): self.liste = liste

Page 22: Konzepte objektorientierter Programmierung

22 Übungen

Aufgabe 6 (siehe www.inf-schule.de 1.12.2.5)

Die folgende Deklaration des Konstruktors erlaubt es, Objekte flexibel mit Anfangswerten zu versehen:class Konto(object): def __init__(self, nummer=0, betrag=0): self.nr = nummer self.stand = betrag

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

>>> k1 = Konto()>>> k1.nr0>>> k1.stand0>>> k2 = Konto(1)>>> k2.nr1>>> k2.stand0>>> k3 = Konto(2, 1000.0)>>> k3.nr2>>> k3.stand1000.0>>> k4 = Konto(betrag=400.0)>>> k4.nr0>>> k4.stand400.0

Erkläre, wie die jeweiligen Attributwerte der Objekte zustande kommen.

Page 23: Konzepte objektorientierter Programmierung

23 Teil 3

Verwaltung von Objekten

Page 24: Konzepte objektorientierter Programmierung

24 Objekte und ihre Identität

Python-Dialog

Aufgabe:Was verbirgt sich wohl hinter der Identitätsnummer eines Objekts?Prüfe mit geeigneten Python-Dialogen, ob sich die Identitätsnummer eines Objekts ändert, wenn sich der Zustand eines Objekts beim Ausführen einer Methode ändert.

>>> k1 = Konto(3)>>> k1<__main__.Konto object at 0x0135D670>>>> id(k1)20305520>>> hex(20305520)'0x135d670'>>> k2 = Konto(4)>>> id(k2)20307184

Page 25: Konzepte objektorientierter Programmierung

25 Konto kopieren?

Python-Dialog

Aufgabe:Stell Vermutungen auf, was anstelle der drei Fragezeichen jeweils steht. Teste, ob deine Vermutungen stimmen. Kannst du dir die Ergebnisse erklären? Benutze auch den id-Operator, um Einsicht über die verwalteten Objekte zu erhalten.

>>> k1 = Konto(6)>>> k2 = k1>>> k1.stand???>>> k2.stand???>>> k2.einzahlen(100.0)>>> k1.stand???>>> k2.stand???>>> k2 = Konto(7)>>> k1.stand???>>> k2.stand???>>>

Page 26: Konzepte objektorientierter Programmierung

26 Identität von Objekten

(Daten-) Objekte haben - analog zu Objekten unserer Lebenswelt - ebenfalls eine Identität. Zur eindeutigen Identifizierung werden sie mit Identitätsnummern versehen.

Verschiedene Objekte unterscheiden sich in ihrer Identitätsnummer. Sie können aber durchaus denselben Objektzustand haben.

Ein Objekt behält während seiner Lebensdauer immer die einmal vergebene Identitätsnummer. Auch wenn sich der Zustand des Objekts verändert, so bleibt doch die Identitätsnummer des Objekts bestehen.

Häufig verwendet hierzu man eine Adresse im Speicher des Rechners als Identitätsnummer. Die Identitätsnummer eines Objekts zeigt dann auf den Speicherbereich, in dem die Daten des Objekts abgelegt sind. Diese Identifikation von Objekten durch eine Lokalisierung im Speicher setzt natürlich voraus, dass Objekte im Speicher nicht hin und her wandern, sondern dass der einmal zugeteilte Speicherbereich während der Lebensdauer eines Objekts bestehen bleibt. Wir gehen im Folgenden von dieser Vorstellung aus.

Page 27: Konzepte objektorientierter Programmierung

27 Zeiger / Referenzen

Eine Variable ist ein Name, der (in der Regel) mit einem Objekt verknüpft ist. Wenn eine Variable ein (Daten-) Objekt verwaltet, dann verwaltet es die Speicheradresse (bzw. Identitäsnummer) dieses Objekts. Da die Speicheradresse auf das Objekt zeigt bzw. das Objekt referenziert, nennt man eine solche Adresse auch Zeiger bzw. Referenz und die Variable zur Verwaltung der Adresse Zeigervariable bzw. Referenzvariable.

Page 28: Konzepte objektorientierter Programmierung

28 Zuweisungen bei Zeigervariablen

k1 = Konto(6)

k2 = k1

k2.einzahlen(100.0)

k2 = Konto(7)

Page 29: Konzepte objektorientierter Programmierung

29 Objekte in Python

Veränderbares Objekt

Unveränder-bares Objekt

Seiteneffekt

kein Seiteneffekt

from konto import *

def null(konto): print(id(konto)) konto.stand = 0.0 print(id(konto))

k = Konto(9)k.einzahlen(100.0)print(k.stand)print(id(k))null(k)print(k.stand)print(id(k))

def null(zahl): print(id(zahl)) zahl = 0.0 print(id(zahl))

z = 100.0print(z)print(id(z))null(z)print(z)print(id(z))

Python unterscheidet zwischen veränder-baren und unveränderbaren Objekten.

Page 30: Konzepte objektorientierter Programmierung

30 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.3.5)

Wenn man den Objektbezeichner vom Python-Interpreter auswerten lässt, dann wird der vom Bezeichner verwaltete Wert angezeigt. Warum zeigt der Python-Dialog, dass hier Zeiger verwaltet werden?

>>> k1 = Konto(6)>>> k2 = k1>>> k1<__main__.Konto object at 0x01DA7F10>>>> k2<__main__.Konto object at 0x01DA7F10>>>> k2 = Konto(8)>>> k2<__main__.Konto object at 0x01DB5CB0>

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

Page 31: Konzepte objektorientierter Programmierung

31 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.3.5)

Jedes Objekt wird zur Identifierung mit einer eindeutigen Identitätsnummer versehen. Mit Hilfe des id-Operators lässt sich diese Identitätsnummer in Python ermitteln. Was zeigt der abgebildete Python-Dialog?

>>> k1 = Konto(6) >>> k2 = k1 >>> id(k1) 31153488 >>> id(k2) 31153488 >>> k2 = Konto(8) >>> id(k2) 31096624

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

Page 32: Konzepte objektorientierter Programmierung

32 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.3.5)

Die Funktion mitNeuemErsten soll dazu dienen, in einer Liste das erste Element auszutauschen. Vegleiche die beiden folgenden Implementierungen und erkläre das unterschiedliche Verhalten.

def mitNeuemErsten(liste, element): hilf = [element] + liste[1:] return hilf

L = [1, 2, 3]M = mitNeuemErsten(L, 0)print(L)print(M)

def mitNeuemErsten(liste, element): liste[0] = element return liste

L = [1, 2, 3]M = mitNeuemErsten(L, 0)print(L)print(M)

Page 33: Konzepte objektorientierter Programmierung

33 Teil 4

Modularisierung und Datenkapselung

Page 34: Konzepte objektorientierter Programmierung

34 Konto überziehen

>>> k = Konto(9)>>> k.stand = 600.0>>> k.stand600.0>>> auszahlungsbetrag = 2750.0>>> k.stand = k.stand - auszahlungsbetrag>>> k.stand-2150.0

Implementierung der Klasse

Nutzung der Klasse

Ein Konto soll höchstens um 1000 Euro überzogen werden dürfen.

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0 self.minimum = -1000.0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): if self.stand - betrag >= self.minimum: self.stand = self.stand - betrag else: print("Auszahlung nicht möglich!")

Aufgabe 1:Warum ist dieser Dialog nicht im Sinne des Bankkontenverwaltungssystems?

Page 35: Konzepte objektorientierter Programmierung

35 Konto überziehen

from konto import Kontok = Konto(9)# Testlaufk.einzahlen(600.0)print(k.getStand())auszahlungsbetrag = 2750.0k.auszahlen(auszahlungsbetrag)print(k.getStand())

Schnittstelle zur Klasse Nutzung der Klasse

Die Entwickler der Klasse Konto veröffentlichen folgende Schnittstelle dieser Klasse:

Aufgabe 2:Warum macht es hier Sinn, die Attribute der Klasse Konto nicht zu veröffentlichen und eine Veränderung von Attributwerten nur über veröffentlichte Merhoden zu erlauben?Aufgabe 3:Im Testprogramm wird die Methode getStand benutzt, die in der Schnittstelle vorgesehen ist. Was soll diese Methode leisten? Ergänze die oben gezeigte Implementierung der Klasse Konto um die noch fehlenden Methoden und führe das Testprogramm aus.

Page 36: Konzepte objektorientierter Programmierung

36 Modularisierung

"Unsere Partyzelte können in verschiedenen Größen aufgebaut werden. Da die Partyzelte und Festzelte aus Modulen bestehen, ist es sehr einfach, sie zu erweitern. Die Abbildung zeigt ein mögliches Kombinationsbeispiel der Module."

Modularisierung ist ein Prinzip, nach dem viele Systeme entwickelt werden. Die Idee besteht darin, das Gesamtsystem nach dem Baukastenprinzip aus Einzelbausteinen (den sogenannten Modulen) zusammenzusetzen.

Ein Softwaremodul ist eine in sich abgeschlossene Einheit, die man vielfältig bei Problem-lösungen einsetzen kann. Es reicht dabei zu wissen, welche Operationen die Einheit dem Benutzer zur Verfügung stellt. Wie die Operationen programmiert sind, muss man dagegen nicht wissen.

Grundidee der objektorientierten Modularisierung ist es, Softwaremodule als Klassen zu konzipieren .

Page 37: Konzepte objektorientierter Programmierung

37 Modularisierung in Python

from konto import Kontok = Konto(9)# Testlaufk.einzahlen(600.0)print(k.getStand())auszahlungsbetrag = 2750.0k.auszahlen(auszahlungsbetrag)print(k.getStand())

from konto import *k = Konto(9)# Testlaufk.einzahlen(600.0)print(k.getStand())auszahlungsbetrag = 2750.0k.auszahlen(auszahlungsbetrag)print(k.getStand())

import kontok = konto.Konto(9)# Testlaufk.einzahlen(600.0)print(k.getStand())auszahlungsbetrag = 2750.0k.auszahlen(auszahlungsbetrag)print(k.getStand())

Der Name "Konto" wird in den aktuellen Namensraum übernommen.

Page 38: Konzepte objektorientierter Programmierung

38 Geheimnisprinzip / Datenkapselung

Beim Autobau wird somit - zumindest in bestimmten Bereichen - das Geheimnisprinzip angewandt. Bestimmte Eigenschaften des Motors können nur über speziell hierfür vorgesehene Schnittstellen ermittelt werden. So kann der aktuelle Ölstand nur an einem hierfür vorgesehenen Messstab abgelesen werden. Änderungen am aktuellen Motorzustand können direkt ebenfalls nur an bestimmten hierfür vorgesehenen Stellen vorgenommen werden. Motoröl lässt sich nur in die hierfür vorgesehene Öffnung einfüllen. Alles weitere über das Innere des Motors bleibt für den normalen Autofahrer unzugänglich und in diesem Sinne geheim.

Bei der objektorientierten Software-Entwicklung geht man völlig analog vor. Nach dem Geheimnisprinzip werden die internen Daten eines Objekts (die in der Regel über Attribute verwaltet werden) so verborgen, dass ein direkter Zugriff hierauf nicht möglich ist. Jeder Zugriff auf interne Daten und jede Veränderung von internen Daten darf nur über spezielle, hierfür vorgesehene Methoden erfolgen. Man nennt diese Vorgehensweise auch Datenkapselung.

Page 39: Konzepte objektorientierter Programmierung

39 Zugriffsrechte / Zugriffsmethoden

Um interne Daten kapseln zu können, werden Zugriffrechte festgelegt. Der Entwickler einer Klasse hat die Möglichkeit, Attribute und Methoden einer Klasse als öffentlich oder privat zu deklarieren. Lesende und schreibende Zugriffe auf Attribute bzw. Methoden eines Objekts sind nur möglich, wenn diese öffentlich sind. Private Attribute bzw. Methoden können dagegen nur bei der Implementierung der betreffenden Klasse benutzt werden.

Im Klassendiagramm werden die Zugriffsrechte auf die Attribute und Methoden mit Hilfe der Symbole + (für öffentlich) und - (für privat) festgelegt.

Verfolgt man die Strategie, alle Attribute als privat zu deklarieren, so besteht keine Möglichkeit, direkt schreibend oder lesend auf Attributwerte zuzugreifen. Um dennoch solche Zugriffe zu erlauben, werden spezielle öffentliche Zugriffsmethoden bereitgestellt. Das Klassendiagramm wird daher um solche Zugriffsmethoden erweitert.

Page 40: Konzepte objektorientierter Programmierung

40 Zugriffsrechte in Python

Ein Attribut / eine Methode wird in Python zu einem privaten Attribut, wenn der Attributname mit zwei Unterstrichen beginnt und nicht mit Unterstrichen endet. Beginnt der Attributname / Methodenname nicht mit einem Unterstrich, so ist das Attribut öffentlich.

class Konto(object): def __init__(self, nummer): self.__nr = nummer self.__stand = 0 self.__minimum = -1000.0

def einzahlen(self, betrag): self.__stand = self.__stand + betrag

def auszahlen(self, betrag): if self.__stand - betrag >= self.__minimum: self.__stand = self.__stand - betrag else: print("Auszahlung nicht möglich!")

def getStand(self): return self.__stand

def setStand(self, stand): if stand >= self.__minimum: self.__stand = stand else: print("Initialisierung nicht möglich!") # ...

Page 41: Konzepte objektorientierter Programmierung

41 Datenkapselung in Python

Wie erwartet kann man auf das private Attribut __stand des neu erzeugten Objekts k nicht zugreifen. Python meldet als Fehler, dass es kein Attribut __stand gibt. Der Aufruf k.__dict__ verrät, woran das liegt. Ein Aufruf wie k.__dict__ listet sämtliche Attribute mit den zugehörigen Attributwerten des betreffenden Objekts auf. Interessant ist hier, dass sich das private Attribut __stand hinter einem anderen Namen versteckt. Wenn man weiß, wie der neue Name - hier _Konto__stand - gebildet wird, dann kann man durchaus auf das betreffende Attribut zugreifen. Also: Private Attribute werden in Python mit anderen Namen versehen, so dass kein direkter Zugriff möglich ist. Kennt man den Namen, hinter dem sich ein privates Attribut verbirgt, so kann man durchaus auf dieses Attribut zugreifen. Python liefert also keinen echten Zugriffsschutz.

>>> k = Konto(3)>>> k.__standTraceback (most recent call last): File ...AttributeError: 'Konto' object has no attribute '__stand'>>> k.__dict__{'_Konto__minimum': -1000.0, '_Konto__nr': 3, '_Konto__stand': 0}>>> k._Konto__stand0

Page 42: Konzepte objektorientierter Programmierung

42 Datenkapselung in Python

Ein erster Zugriff auf das private Attribut __stand scheitert. Dann aber ist es - entgegen aller Zugriffslogik - scheinbar möglich, dem privaten Attribut __stand einen Wert zuzuweisen. Der Aufruf k.__dict__ erklärt erst, was hier passiert ist. Neben dem privaten Attribut __stand, das sich hinter dem neuen Namen _Konto__stand versteckt, gibt es noch öffentliches Attribut __stand, auf das man direkt zugreifen kann.

>>> k = Konto(3)>>> k.__standTraceback (most recent call last): File ...AttributeError: 'Konto' object has no attribute '__stand'>>> k.__dict__{_Konto__minimum': -1000.0, '_Konto__nr': 3, '_Konto__stand': 0}>>> k.__stand = 100.0>>> k.__stand100.0>>> k.__dict__{_Konto__minimum': -1000.0, '_Konto__nr': 3, '_Konto__stand': 0, '__stand': 100.0}

Wir werden im Folgenden bei der Implementierung von Klassen in Python keine Attribute als private Attribute deklarieren. In der Regel werden wir auch keine Zugriffsmethoden einführen und nutzen. Nur in begründeten Ausnahmefällen werden wir von dieser Vereinbarung abweichen.

Page 43: Konzepte objektorientierter Programmierung

43 Schnittstellen

Die Schnittstelle einer Klasse liefert alle Informationen, die man benötigt, um die Klasse benutzen zu können. Hierzu gehört eine genaue Beschreibung aller öffentlichen Attribute und Methoden der Klasse. Für jedes Attribut benötigt man den erwarteten Datentyp, für jede Methode die Signatur (d. h. die genaue Festlegung der Parametertypen und bei Funktionen des Rückgabetyps) und eine Verhaltensbeschreibung.

Konto(nummer: int)

nachher: Ein Objekt der Klasse Konto ist erzeugt. Der Wert des Attributs nr entspricht dem übergebenen Wert des Parameters nummer, der Wert des Attributs stand beträgt 0, der Wert des Attributs minimum beträgt -1000.0.

auszahlen(betrag: float)

vorher: Das Konto-Objekt hat einen beliebigen Zustand.

nachher: Der Wert des Attributs stand des Konto-Objekts ist um den übergebenen Wert des Parameters betrag reduziert.

Page 44: Konzepte objektorientierter Programmierung

44 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.4.8)

Zur Klasse Wuerfel soll folgende Implementierung in einer Datei wuerfel.py abgespeichert sein:

from random import randint

class Wuerfel(object): def __init__(self): self.augen = 1

def werfen(self): self.augen = randint(1, 6)from wuerfel import *# Würfelprogrammw = Wuerfel()w.werfen()versuche = 1while w.augen != 6: w.werfen() versuche = versuche + 1print("Versuche:", versuche)

(a) Was leistet das folgende Programm, das das Modul Wuerfel als Baustein benutzt?

(b) Es soll getestet werden, wie oft man drei Würfel werfen muss, bis mindestens einer eine 6 liefert. Entwickle ein geeignetes Simulationsprogramm, das die Klasse Wuerfel als Baustein benutzt.

Page 45: Konzepte objektorientierter Programmierung

45 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.4.8)

Folgende Klassen sollen als Bausteine zur Simulation des Spiels "chuck a luck" zur Verfügung gestellt werden:

>>> k = Konto(100)>>> s = Spielzahl()>>> wA = Wuerfel()>>> wB = Wuerfel()>>> wC = Wuerfel()>>> k.abheben(1)>>> k.stand99>>> s.setzen(3)>>> s.zahl3>>> wA.werfen()>>> wB.werfen()>>> wC.werfen()>>> wA.augen3>>> wB.augen6>>> wC.augen2>>> k.einzahlen(2)>>> k.stand101

(a) Implementiere diese Klassen. Mit Hilfe dieser Bausteine sollen dann Python-Dialoge wie der folgende möglich sein.

(b) Mit Hilfe eines Simulationsprogramms soll ermittelt werden, ob das chuck-a-luck-Spiel fair ist.

Page 46: Konzepte objektorientierter Programmierung

46 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.4.8)

(a) Erstell ein Klassendiagramm und eine Schnittstellenbeschreibung zur Klasse Bruch.

(b) Entwickle ein Testprogramm, das die Klasse Bruch als Modul benutzt.

... def vollstaendigKuerzen(self): # ggT von Zähler und Nenner best. x = self.zaehler y = self.nenner while y > 0: h = x % y x = y y = h ggt = x # kürzen self.kuerzen(ggt)

def add(self, b): x1 = self.zaehler x2 = self.nenner y1 = b.zaehler y2 = b.nenner z1 = x1*y2 + x2*y1 z2 = x2*y2 self.zaehler = z1 self.nenner = z2 self.vollstaendigKuerzen()

class Bruch(object): def __init__(self, z, n): self.zaehler = z self.nenner = n

def erweitern(self, k): self.zaehler = self.zaehler * k self.nenner = self.nenner * k

def kuerzen(self, k): if (self.zaehler % k == 0) and \ (self.nenner % k == 0): self.zaehler = self.zaehler // k self.nenner = self.nenner // k...

(c) Füge der Klasse Bruch weitere Operationen hinzu und teste diese Erweiterung.

Page 47: Konzepte objektorientierter Programmierung

47 Übungen

Aufgabe 5 (siehe www.inf-schule.de 1.12.4.8)

Teste die Einbindung folgender Modulimporte und ihre Auswirkung auf den globalen Namensraum.

Warum wird bei sehr umfangreichen Modulen empfohlen, die erste oder dritte der oben aufgelisteten Einbindungsvarianten zu benutzen?

>>> from random import randint>>> globals()

>>> from random import *>>> globals()

>>> import random>>> globals()

Page 48: Konzepte objektorientierter Programmierung

48 Übungen

Aufgabe 6 (siehe www.inf-schule.de 1.12.4.8)

(a) Teste diese Implementierung der Klasse Bruch. Irgend etwas stimmt hier nicht. Findest du den Fehler? Benutze die Operation __dict__() zur Fehlersuche. Erkläre, was hier schiefläuft.

(b) Warum ist es so schwierig, Flüchtigkeitsfehler wie den oben gezeigten zu finden?

class Bruch(object): def __init__(self, z, n): self.zaehler = z self.nenner = n

def erweitern(self, k): self.zahler = self.zaehler * k self.nenner = self.nenner * k

def kuerzen(self, k): if (self.zaehler % k == 0) and \ (self.nenner % k == 0): self.zaehler = self.zaehler // k self.nenner = self.nenner // k

Page 49: Konzepte objektorientierter Programmierung

49 Teil 5

Beziehungen

Page 50: Konzepte objektorientierter Programmierung

50 Verwaltung des Kontoinhabers

SKonto-Nr.5 Adriana Müller Kontoauszug

Blatt 3

Datum Erläuterung Betrag

01.07.2009 Handykosten 45.00 -

08.07.2009 Zuschuss von Oma und Opa 100.00 +

10.07.2009 Schuhe 80.00 -

Kontostand in EUR, 11.07.2009 50.00 +

Der Kontoinhaber soll jetzt ebenfalls mitverwaltet werden. Hierzu muss das Objektmodell erweitert werden. Mehrere Vorschläge stehen zur Diskussion

Aufgabe:Vergleiche die folgenden Vorschläge.

Vorschlag 1: Vorschlag 2:

Page 51: Konzepte objektorientierter Programmierung

51 Verwaltung des Kontoinhabers

Aufgabe:Welche Nachteile zeigen sich bei Vorschlag 2, wenn es mehrere Konten und mehrere Kunden gibt? Vergleiche Vorschlag 2 mit Vorschlag 3.

Vorschlag 3:

Vorschlag 2:

Page 52: Konzepte objektorientierter Programmierung

52 Verwaltung des Kontoinhabers

Aufgabe:Erkläre, wie die Objektkonstellation aus Vorschlag 3 hier realisiert wird. Stell auch eine Vermutung auf, was das Testprogramm auf dem Bildschirm ausgibt.

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Kunde(object): def __init__(self, name, vorname): self.name = name self.vorname = vorname

from konto_kunde import *# Erzeugung der Objektekonto1 = Konto(5)konto2 = Konto(11)konto2.stand = 200.0kunde1 = Kunde("Müller", "Adriana")kunde2 = Kunde("Meier", "Anatol")konto1.inhaber = kunde2konto2.inhaber = kunde1# Ausgabenprint("Kontonummer: ", konto1.nr)print("Inhaber(in): ", konto1.inhaber.vorname, \ konto1.inhaber.name)print("Kontostand: ", konto1.stand)print()print("Kontonummer: ", konto2.nr)print("Inhaber(in): ", konto2.inhaber.vorname, \ konto2.inhaber.name)print("Kontostand: ", konto2.stand)

Page 53: Konzepte objektorientierter Programmierung

53 Beziehung

Wenn ein Objekt über einen Zeiger (eine Referenz) Zugriff auf ein anderes Objekt hat, so liegt eine (gerichtete) Beziehung zwischen den Objekten vor.

Objektdiagramm

Klassendiagramm

Mit Hilfe eines Aufrufs wie z.B. konto1.inhaber kann das Konto-Objekt konto1 auf Daten des zugeordneten Kunde-Objekts zugreifen, z.B. mit konto1.inhaber.name auf das entsprechende Attribut. Das Konto-Objekt konto1 hat somit Zugriff auf ein Kunde-Objekt, z.B. kunde2. Man sagt auch, dass das Konto-Objekt konto1 in Beziehung zum Kunde-Objekt kunde2 steht.

Page 54: Konzepte objektorientierter Programmierung

54 Beziehungsmuster

Muster: Objekt der Klasse A kennt Objekt der Klasse B

Muster: Objekt der Klasse A kennt Objekt der Klasse B und umgekehrt

Muster: Objekt der Klasse A kennt mehrere Objekte der Klasse B

Muster: Objekt der Klasse A erzeugt Objekt der Klasse B

Page 55: Konzepte objektorientierter Programmierung

55 Implementierung von Beziehungen

Muster: Objekt der Klasse A kennt Objekt der Klasse B

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Kunde(object): def __init__(self, name, vorname): self.name = name self.vorname = vorname

from bank0 import *# Erzeugung der Objektekonto1 = Konto(5)konto2 = Konto(11)konto2.stand = 200.0kunde1 = Kunde("Müller", "Adriana")kunde2 = Kunde("Meier", "Anatol")konto1.inhaber = kunde2konto2.inhaber = kunde1

Page 56: Konzepte objektorientierter Programmierung

56 Implementierung von Beziehungen

Muster: Objekt der Klasse A kennt Objekt der Klasse B und umgekehrt

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Kunde(object): def __init__(self, name, vorname): self.name = name self.vorname = vorname self.konto = None

from bank1 import *# Erzeugung der Objektekonto1 = Konto(5)konto2 = Konto(11)konto2.stand = 200.0kunde1 = Kunde("Müller", "Adriana")kunde2 = Kunde("Meier", "Anatol")konto1.inhaber = kunde2konto2.inhaber = kunde1kunde1.konto = konto2kunde2.konto = konto1

Page 57: Konzepte objektorientierter Programmierung

57 Implementierung von Beziehungen

Muster: Objekt der Klasse A kennt mehrere Objekte der Klasse B

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Kunde(object): def __init__(self, name, vorname): self.name = name self.vorname = vorname self.konten = []

def kontoHinzufuegen(self, konto): self.konten = self.konten + [konto]

from bank2 import *# Erzeugung der Objektekonto1 = Konto(5)konto2 = Konto(11)konto2.stand = 200.0konto3 = Konto(19)konto3.stand = 150.0konto4 = Konto(21)konto4.stand = -50.0kunde1 = Kunde("Müller", "Adriana")kunde2 = Kunde("Meier", "Anatol")konto1.inhaber = kunde2konto2.inhaber = kunde1konto3.inhaber = kunde1konto4.inhaber = kunde1kunde1.kontoHinzufuegen(konto2)kunde1.kontoHinzufuegen(konto3)kunde1.kontoHinzufuegen(konto4)kunde2.kontoHinzufuegen(konto1)

Liste

Page 58: Konzepte objektorientierter Programmierung

58 Implementierung von Beziehungen

Muster: Objekt der Klasse A erzeugt Objekte der Klasse B

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Bank(object): def __init__(self): self.konten = [] self.naechsteKontoNr = 0

def erzeugeKonto(self): konto = Konto(self.maxKontoNr) self.konten = self.konten + [konto] self.naechsteKontoNr = self.naechsteKontoNr + 1

from bank3 import *from random import *# Erzeugung der Objektebank = Bank()for i in range(8): bank.erzeugeKonto()for konto in bank.konten: konto.einzahlen(float(randint(0, 100)))

Page 59: Konzepte objektorientierter Programmierung

59 Operationen als Dienste

Objekte können (in aller Regel) bestimmte Operationen mit den von ihnen verwalteten Daten ausführen. Die Ausführung einer Operationen wird als Dienst anderen Objekten zur Verfügung gestellt. Andere Objekte können den zur Verfügung gestellten Dienst dann nutzen. Hier wird also die Anbieter-Nutzer-Sichtweise benutzt.

Ein Bank-Objekt bietet z.B. den Dienst ueberweisen an.Ein Konto-Objekt bietet z.B. den Dienst einzahlen an.

Page 60: Konzepte objektorientierter Programmierung

60 Interaktion zwischen Objekten

Wenn das Bank-Objekt den Dienst "ueberweisen" ausführt, dann schickt es zunächst eine Nachricht auszahlen(...) an das betreffende Konto-Objekt und anschließend eine Nachricht einzahlen(...) an das andere betreffende Konto-Objekt. Das Bank-Objekt interagiert also hier mit zwei Konto-Objekten. Dies ist deshalb möglich, weil das Bank-Objekt gemäß Klassendiagramm oben in Beziehung zu den Konto-Objekten steht.

Die Analogien zur Lebenswelt ermöglichen es, die Ausführung objektorientierter Programme in einem Rollenspiel zu verdeutlichen, bei dem Personen die Rolle von Objekten übernehmen.

Page 61: Konzepte objektorientierter Programmierung

61 Interaktion zwischen Objekten

Wenn ein Objekt den Dienst eines anderen Objekt nutzen will, dann schickt es ihm eine Nachricht. Das Senden einer Nachricht bedeutet, ein Objekt zu veranlassen, eine seiner als Dienste zur Verfügung gestellten Operationen. Das Versenden von Nachrichten wird als Interaktion zwischen Objekten gedeutet. Voraussetzung für eine Interaktion zwischen Objekten ist, dass diese miteinander in Beziehung stehen.

Wenn das Bank-Objekt den Dienst "ueberweisen" ausführt, dann schickt es zunächst eine Nachricht auszahlen(...) an das betreffende Konto-Objekt und anschließend eine Nachricht einzahlen(...) an das andere betreffende Konto-Objekt. Das Bank-Objekt interagiert also hier mit zwei Konto-Objekten. Dies ist deshalb möglich, weil das Bank-Objekt gemäß Klassendiagramm oben in Beziehung zu den Konto-Objekten steht.

Sequenzdiagramm

Page 62: Konzepte objektorientierter Programmierung

62 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.5.6)

Erzeuge Objekte, die folgende Situation modellieren: Kunde Werner Schmidt hat das Konto mit der Nummer 23. Kundin Theresa Meier hat das Konto mit der Nummer 42. Kundin Alexandra Roth hat das Konto mit der Nummer 15.

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): self.stand = self.stand - betrag

class Kunde(object): def __init__(self, name, vorname): self.name = name self.vorname = vorname

Page 63: Konzepte objektorientierter Programmierung

63 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.5.6)

Ein Kunde soll neben einem Erstkonto auch ein Zweitkonto haben können.

(a) Beschreibe eine typische Situation in dieser Bankwelt mit einem Objektdiagramm.

(b) Beschreibe die Bankwelt auch mit einem Klassendiagramm.

(c) Entwickle eine Implementierung zu dieser Bankwelt und ein Testprogramm passend zu Aufgabe (a).

Page 64: Konzepte objektorientierter Programmierung

64 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.5.6)

In der freien Enzyklopädie Wikipedia werden Artikel zu Stichwörtern von Benutzern verfasst. Eine erste Modellierung der Klassen Artikel und Benutzer könnte wie folgt aussehen:

(a) Implementiere die Klassen und erzeuge Objekte zur Beschreibung folgender Situation:

* Der Artikel zum Stichwort HTML wurde vom Benutzer helmut03 verfasst.

* Der Artikel zum Stichwort CSS wurde vom Benutzer loreley verfasst.

* Der Artikel zum Stichwort Barrierefreiheit wurde vom Benutzer loreley verfasst.

Page 65: Konzepte objektorientierter Programmierung

65 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.5.6)

Das Modell soll so erweitert werden, dass Artikel von Benutzern überarbeitet werden können:

(b) Implementiere das erweiterte Modell und erzeuge eine typische Objektsituation. Verdeutliche die erzeugte Objektsituation auch mit einem Objektdiagramm.

(c) Wie müsste man die Klasse Benutzer erweitern, wenn hier auch die Mitarbeit an Artikeln mit einem Referenzattribut erfasst werden soll.

Page 66: Konzepte objektorientierter Programmierung

66 Übungen

Aufgabe 4 (siehe www.inf-schule.de 1.12.5.6)

Ein Geometrieprogramm soll verschiedene geometrische Objekte verwalten. Kannst du passende Klassen konzipieren und implementieren, so dass folgendes Testprogramm sinnvoll ausgeführt werden kann.

from geometrie import *# Punktep1 = Punkt(0, 0)p2 = Punkt(0, 10)p3 = Punkt(10, 10)p4 = Punkt(10, 0)p5 = Punkt(5, 15)# Rechtecke und Dreieck (als n-Eck)rechteck = Rechteck(p1, p3)dreieck = Neck([p2, p3, p5])# Haus des Nikolaus als Figurhaus_nikolaus = Figur()haus_nikolaus.hinzufuegen(rechteck)haus_nikolaus.hinzufuegen(dreieck)# Punkt verschieben und ausgebenp1.verschieben(4, 1)...

Page 67: Konzepte objektorientierter Programmierung

67 Teil 6

Miniwelt und Datenmodell

Page 68: Konzepte objektorientierter Programmierung

68 Bankwelt im Computer

SKonto-Nr.5 Adriana Müller Kontoauszug

Blatt 3

Datum Erläuterung Betrag

01.07.2009 Handykosten 45.00 -

08.07.2009 Zuschuss von Oma und Opa 100.00 +

10.07.2009 Schuhe 80.00 -

Kontostand in EUR, 11.07.2009 50.00 +

Die Bankwelt mit bestimmten Gegenständen (Kunden, Konten, ...) und Vorgängen (Ein-, Auszahlungen, ...) soll in einem Programm geeignet erfasst werden.

Page 69: Konzepte objektorientierter Programmierung

69 Bankwelt im Computer

SKonto-Nr.5 Adriana Müller Kontoauszug

Blatt 3

Datum Erläuterung Betrag

01.07.2009 Handykosten 45.00 -

08.07.2009 Zuschuss von Oma und Opa 100.00 +

10.07.2009 Schuhe 80.00 -

Kontostand in EUR, 11.07.2009 50.00 +

Aufgabe:Welche Objekte sind für welche Aufgaben zuständig?Welche Vereinfachungen sind bei dieser Beschreibung einer Bankwelt vorgenommen?

Page 70: Konzepte objektorientierter Programmierung

70 Bankwelt im Computer

from bank import *bank = Bank()# Konten eröffnenbank.kontoEroeffnen("Müller", "Adriana", 2101)bank.kontoEroeffnen("Meier", "Adrian", 1507)bank.kontoEroeffnen("Schuster", "Christiane", 1313)bank.kontoEroeffnen("Weber", "Alexander", 2276)# Ausgabe der kontenfor kunde in bank.kunden: print("Kunde:") print("Name:", kunde.name) print("Vorname:", kunde.vorname) print("Kontonummer:", kunde.konto.nr) print("Kontostand:", kunde.konto.stand) print()# Transaktionprint("Einzahlung")pin = int(input("PIN:"))if bank.existiertPIN(pin): meineKontoNr = bank.getKontoNr(pin) betrag = float(input("Betrag:")) bank.einzahlen(meineKontoNr, betrag) ...

Aufgabe:Lade dir die Datei bank.py mit einer Implementierung der Klassen herunter. Versuche, mit den Objekten Vorgänge der Bankwelt durchzuspielen. Das folgende Python-Testprogramm zeigt, wie das gehen könnte.

Page 71: Konzepte objektorientierter Programmierung

71 Miniwelt

Mit Miniwelt bezeichnen wir den Weltausschnitt / Gegenstandsbereich, der dem zu entwickelnden Programm (Software-System) zu Grunde liegt.

SKonto-Nr.5 Adriana Müller Kontoauszug

Blatt 3

Datum Erläuterung Betrag

01.07.2009 Handykosten 45.00 -

08.07.2009 Zuschuss von Oma und Opa 100.00 +

10.07.2009 Schuhe 80.00 -

Kontostand in EUR, 11.07.2009 50.00 +

Page 72: Konzepte objektorientierter Programmierung

72 Datenmodell

Ein Modell ist eine vereinfachende Darstellung einer Miniwelt, die (für einen bestimmten Zweck ausgewählte) Teilaspekte der Miniwelt strukturgetreu beschreibt.

Aufgabe eines objektorientiertes Datenmodells ist es, die Struktur der Miniwelt mit Hilfe von Objekten und deren Beziehungen zu beschreiben.

Page 73: Konzepte objektorientierter Programmierung

73 Zuständigkeiten

Bei der Entwicklung komplexer Software-Systeme ist es günstig, dieses System aus mehreren Objekten zusammenzusetzen. Jedes Objekt sollte dabei für einen bestimmten Aufgabenbereich zuständig sein. Ein solches System aus Objekten mit klar umgrenzten Zuständigkeiten erhöht die Durchschaubarkeit des gesamten Software-Systems und erleichtert es, das System nachträglich abzuändern oder zu erweitern.Objekt der Klasse Kunde: verwaltet die Kundendaten

Objekt der Klasse Konto: verwaltet die Kontodaten; führt Ein- und Auszahlungen aus

Objekt der Klasse Bank: erzeugt und verwaltet alle Kunde-Objekte und Konto-Objekte; veranlasst alle Geldtransfers zwischen Konten; ...

Page 74: Konzepte objektorientierter Programmierung

74 UML

UML steht für uniform modeling language und ist eine normierte Bildsprache, mit der man objektorientierte Modelle beschreiben kann.

Sequenzdiagramm

Klassendiagramm

Objektdiagramm

Page 75: Konzepte objektorientierter Programmierung

75 UML-Editor

Violet ist ein sehr einfaches, frei nutzbares Werkzeug zur Erstellung von UML-Diagrammen.siehe: http://www.horstmann.com/violet/

Page 76: Konzepte objektorientierter Programmierung

76 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.6.6)

Beim chuck-a-luck-Spiel soll ein Objekt der Klasse Spiel alle beteiligten Objekte verwalten und die Spielaktionen als Operationen zur Verfügung stellen.

(a) Skizziere ein Objektdiagramm zur Miniwelt chuck-a-luck.

(b) Woran erkennt man im Klassendiagramm, dass das Spiel-Objekt für die Erzeugung der weiteren Objekte zuständig ist? Welche weiteren Zuständigkeiten hat das Spiel-Objekt?

(c) Implementiere dieses Modell. Teste es wie folgt. from chuckaluck import *# Erzeugung der Objektespiel = Spiel()# Durchführung eines Spielsspiel.einsatzZahlen()spiel.spielzahlSetzen(5)spiel.wuerfelWerfen()spiel.gewinnAuszahlen()# Ausgabe der Spielprint("Würfel A:", spiel.wuerfelA.augen)...

Page 77: Konzepte objektorientierter Programmierung

77 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.6.6)

Das folgende Klassendiagramm zeigt ein System, mit dem man die Entwicklung einer Population simulieren kann.

(a) Implementiere die Klasse Population so, dass die Mäusepopulation aus ... (siehe Einstieg - Mäusepopulation) als Miniwelt erfasst wird.

(b) Implementiere die Klasse Simulator so, dass sie die Entwicklung der verwalteten Population beschreibt.

(c) Erstell ein geeignetes Testprogramm, um die Implementierung zu überprüfen..

(d) Was müsste am Datenmodell verändert werden, wenn man die Population aus ... (siehe Miniprojekt) modellieren wollte?

Page 78: Konzepte objektorientierter Programmierung

78 Übungen

Aufgabe 3 (siehe www.inf-schule.de 1.12.6.6)

Ein Zahlenschloss bestehe aus drei Einstellrädern, mit denen die Ziffern der Schlüsselzahl einzeln eingestellt werden können. Hat man die Schlüsselzahl richtig getroffen, dann ist das Schloss offen.

Entwickle ein objektorientiertes Datenmodell, das die vorliegende Miniwelt möglichst strukturgetreu beschreibt. Stell das Datenmodell auch mit Hilfe von UML-Diagrammen dar.

Implementiere und teste das Datenmodell.

Page 79: Konzepte objektorientierter Programmierung

79 Teil 7

Datenmodell und grafische Benutzeroberfläche

Page 80: Konzepte objektorientierter Programmierung

80 Eine GUI zur Bankwelt

Das bisher entwickelte Programm zur Verwaltung von Bankkonten soll um eine grafische Benutzeroberfläche erweitert werden. Der Benutzer soll die Möglichkeit haben, wie an einem Terminal in der Bank seine Bankgeschäfte zu erledigen. Am Terminal kann man sich den aktuellen Kontostand anzeigen lassen, Geldbeträge ein- und auszahlen und auch Überweisungen vorzunehmen.

Page 81: Konzepte objektorientierter Programmierung

81 Eine GUI zur Bankwelt

Aufgabe:Das gezeigte Programm (siehe www.inf-schule.de ...) enthält zwar noch Implementierungslücken, ist aber nichtsdestotrotz lauffähig. Teste zunächst das Programm. Mache dich auch mit dem Quelltext vertaut. Analysiere insbesondere die schon implementierten Ereignisverarbeitungsprozeduren. Implementiere die noch fehlenden Implementierungen.

#-----------------------------------------------------------# Datenmodell#-----------------------------------------------------------

from bank import *bank = Bank()bank.initBank()

#-----------------------------------------------------------# GUI#-----------------------------------------------------------

from tkinter import *

# ... Prozeduren zur Ereignisverarbeitung

# Erzeugung des Fenstersfenster = Tk()fenster.title("Bank")fenster.geometry('230x330')...

Page 82: Konzepte objektorientierter Programmierung

82 Eine GUI zur Bankwelt

from tkinter import *

class GUIBank(object): def __init__(self, bank): # Referenzattribute zum Datenmodell self.bank = bank # Erzeugung des Fensters self.fenster = Tk() self.fenster.title("Bank") self.fenster.geometry('230x330') # Rahmen PIN self.rahmenPIN = Frame(master=self.fenster, background="#FFCFC9") self.rahmenPIN.place(x=5, y=5, width=220, height=30) # Label mit Aufschrift PIN self.labelPIN = Label(master=self.rahmenPIN, background="white", text="PIN") self.labelPIN.place(x=5, y=5, width=145, height=20) # Entry für die PIN self.entryPIN = Entry(master=self.rahmenPIN) self.entryPIN.place(x=155, y=5, width=60, height=20) ... def Button_Anzeigen_Click(self): pin = int(self.entryPIN.get()) ...

Aufgabe:Der folgende Quelltextauszug zeigt eine andere Implementierung der grafischen Benutzeroberfläche. Hier wird ein zusätzliches Objekt benutzt, um sämtliche GUI-Objekte zu verwalten. Analysiere das Programm.

Page 83: Konzepte objektorientierter Programmierung

83 Eine GUI zur Bankwelt

#-----------------------------------------------------------# Datenmodellobjekte#-----------------------------------------------------------

from bank import *bank = Bank()bank.initBank()

#-----------------------------------------------------------# GUI-Objekte#-----------------------------------------------------------

from guibank import *guibank = GUIBank(bank)

Aufgabe:Welche Beziehungen bestehen zwischen den Objekten? Verdeutliche dies mit einem Objekt- und Klassendiagramm.

Page 84: Konzepte objektorientierter Programmierung

84 Zwei-Komponenten-Architektur

#----------------------------------# Datenmodellobjekte#----------------------------------

from bank import *bank = Bank()bank.initBank()

#----------------------------------# GUI-Objekte#----------------------------------

from guibank import *guibank = GUIBank(bank)

Das bisher entwickelte System zur Verwaltung von Bankkonten hat eine Zwei-Komponenten-Architektur. Die eine Komponente wird vom Datenmodell gebildet. Diese Komponente ist so konzipiert, dass sie ohne eine grafische Benutzeroberfläche benutzt werden kann. Die andere Komponente umfasst alle Klassen, die für die Erzeugung und Verwaltung der grafischen Benutzeroberfläche benötigt werden. Da Objekte dieser Klassen u. a. für die Darstellung des Datenmodells zuständig sind, dürfen sie Zugriff auf Datenmodell-Objekte haben.

Page 85: Konzepte objektorientierter Programmierung

85 Trennung Datenmodell - GUI

Die Trennung zwischen Datenmodell und GUI ist ein Prinzip bei der Entwicklung von Systemen mit grafischer Benutzeroberfläche, das hilft, klar strukturierte und gut wartbare Programme zu erstellen: Während GUI-Objekte auf Objekte des Datenmodells zugreifen dürfen, ist der umgekehrte Zugriff nicht erlaubt.

Page 86: Konzepte objektorientierter Programmierung

86 Model - View - Control

Bisher war das GUI-Objekt sowohl für die Präsentation der Daten auf der Benutzerober-fläche, als auch für die Ereignisverarbeitung zuständig. Diese beiden Zuständigkeiten sollen jetzt aufgeteilt werden: Einerseits soll es Präsentations-objekte geben, die nur für die Darstellung der Daten zuständig sind, andererseits Steuerungs-objekte, die die Verbindungen zwischen Präsentationsobjekten und Datenmodellobjekten herstellen und die Ereignisverarbeitung festlegen. Diese weitere Aufteilung der Zuständigkeiten soll spätere Änderungen oder Erweiterungen des Softwaresystems erleichtern und eine Wiederverwendbarkeit einzelnen Komponenten ermöglichen.

Model

View

Control

Page 87: Konzepte objektorientierter Programmierung

87 Model - View - Control

Modelclass Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0.0 self.inhaber = None ...

class Kunde(object): def __init__(self, name, vorname, pin): self.name = name self.vorname = vorname self.pin = pin self.konto= None ...

class Bank(object): def __init__(self): self.konten = [] self.kunden = [] self.naechsteKontoNr = 0 ...

Page 88: Konzepte objektorientierter Programmierung

88 Model - View - Control

Viewfrom tkinter import *

class GUIBank(object): def __init__(self, bank, \ cbAnzeigen, cbEinzahlen, cbAuszahlen, cbUeberweisen): # Referenzattribute zum Datenmodell self.bank = bank self.cbAnzeigen = cbAnzeigen self.cbEinzahlen = cbEinzahlen self.cbAuszahlen = cbAuszahlen self.cbUeberweisen = cbUeberweisen # Erzeugung des Fensters self.fenster = Tk() self.fenster.title("Bank") self.fenster.geometry('230x330') ... # Button Anzeigen self.buttonAnzeigen = Button(master=self.rahmenKonto, text="anzeigen", \ command=self.cbAnzeigen) self.buttonAnzeigen.place(x=5, y=55, width=145, height=20) ... # kein mainloop hier

Page 89: Konzepte objektorientierter Programmierung

89 Model - View - Control

Control

from model_bank import *from view_bank import *class Controler(object): def __init__(self): # Erzeugung der Datenmodell-Objekte self.bank = Bank() self.bank.initBank() # Erzeugung und Initialisierung der GUI self.guibank = GUIBank(self.bank, self.buttonAnzeigen, self.buttonEinzahlen, ...) # Ereignisschreife self.guibank.fenster.mainloop() def buttonAnzeigen(self): pin = int(self.guibank.entryPIN.get()) if self.bank.existiertPIN(pin): kunde = self.bank.getKunde(pin) self.guibank.labelKontonummer.config(text=str(kunde.konto.nr)) self.guibank.labelKontostand.config(text=str(kunde.konto.stand)) else: self.guibank.labelKontonummer.config(text="") self.guibank.labelKontostand.config(text="") ...controler = Controler()

Page 90: Konzepte objektorientierter Programmierung

90 Model - View - Control

Aufgabe eines GUIBank-Objekts ist es, die grafische Benutzeroberfläche zu erzeugen.

Model

View

Control

Aufgabe eines Controler-Objekts ist es, die Datenmodell- und GUI-Objekte zu erzeugen und zu verknüpfen.

Aufgabe eines Model-Objekts ist es, einen Aspekt der Miniwelt abzubilden..

Beachte, dass ein Controler-Objekt Zugriff auf Model- und View-Objekte hat.

Page 91: Konzepte objektorientierter Programmierung

91

class GUIBank(object):

def __init__(self, bank, cbAnzeigen, cbEinzahlen, cbAuszahlen, cbUeberweisen): # Referenzattribute zum Datenmodell self.bank = bank self.cbAnzeigen = cbAnzeigen self.cbEinzahlen = cbEinzahlen self.cbAuszahlen = cbAuszahlen self.cbUeberweisen = cbUeberweisen # Erzeugung des Fensters self.fenster = Tk() self.fenster.title("Bank") self.fenster.geometry('230x330') ... # Button Anzeigen self.buttonAnzeigen = Button(master=self.rahmenKonto, text="anzeigen", \ command=self.cbAnzeigen) self.buttonAnzeigen.place(x=5, y=55, width=145, height=20) ...

Callback-Funktion

Parameter für eine Callback-Funktion

Eine Callback-Funktion (bzw. Rückruffunktion) ist eine Funktion, die einer anderen Funktion als Parameter übergeben wird und von dieser unter gewissen Bedingungen aufgerufen wird.

Page 92: Konzepte objektorientierter Programmierung

92

class Controler(object):

def __init__(self): # Erzeugung der Datenmodell-Objekte self.bank = Bank() self.bank.initBank() # Erzeugung und Initialisierung der GUI self.guibank = GUIBank(self.bank, self.buttonAnzeigen, self.buttonEinzahlen, ...) # Ereignisschreife self.guibank.fenster.mainloop()

def buttonAnzeigen(self): pin = int(self.guibank.entryPIN.get()) if self.bank.existiertPIN(pin): kunde = self.bank.getKunde(pin) self.guibank.labelKontonummer.config(text=str(kunde.konto.nr)) self.guibank.labelKontostand.config(text=str(kunde.konto.stand)) else: ...

Callback-Funktion

Callback-Funktion

Eine Callback-Funktion (bzw. Rückruffunktion) ist eine Funktion, die einer anderen Funktion als Parameter übergeben wird und von dieser unter gewissen Bedingungen aufgerufen wird.

Callback-Funktion

Page 93: Konzepte objektorientierter Programmierung

93

class Uhr(object): ... def tick(self): if self.sekunden < 59: self.sekunden = self.sekunden + 1 else: self.sekunden = 0 if self.minuten < 59: self.minuten = self.minuten + 1 else: ...

Strategie: Befragen

Das Objekt guiuhr nutzt eine Strategie, die man Befragen oder Polling nennt. Das Objekt guiuhr weiß genau, wann sich das Datenmodell ändert (nach jedem Anklicken der Schaltfläche) und besorgt sich die geänderten Daten zur Anzeige auf dem vorgesehenen Label.

from tkinter import *class GUIUhr(object): def __init__(self, uhr): # Referenzattribute zum Datenmodell self.uhr = uhr # Erzeugung des Fensters ... # Button self.buttonTick = Button(..., command=self.Button_Tick_Click) ... def Button_Tick_Click(self): # Verarbeitung der Daten self.uhr.tick() # Anzeige der Daten uhrzeit = str(self.uhr.stunden) + ":" + \ str(self.uhr.minuten) + ":" + \ str(self.uhr.sekunden) self.labelUhr.config(text=uhrzeit)

Befragen

Änderung# Datenmodellfrom uhr import *uhr = Uhr()# GUI-Objektfrom guiuhr import *guiuhr = GUIUhr(uhr)guiuhr.fenster.mainloop()

Page 94: Konzepte objektorientierter Programmierung

94

import threading, time

class Timer(threading.Thread): ...

class Uhr(object): def __init__(self): ... self.aktiv = False self.beobachter = None

def setBeobachter(self, beobachter): self.beobachter = beobachter

def stellen(self, h, m, s): self.stunden.setzen(h) self.minuten.setzen(m) self.sekunden.setzen(s) self.beobachter.anzeigeAktualisieren()

Strategie: Beobachten

Das Objekt guiuhr nutzt hier eine Strategie, die man Beobachten nennt. Das Objekt guiuhr wird als registriertes beobachtendes Objekt jeweils benachrichtigt, wenn sich das Datenmodell verändert hat.

... def stoppen(self): self.aktiv = False

def tick(self): if self.sekunden < 59: self.sekunden = self.sekunden + 1 else: self.sekunden = 0 ... self.beobachter.anzeigeAktualisieren() if self.aktiv: self.timer = Timer(1, self.tick) self.timer.start()

def ticken(self): self.aktiv = True self.timer = Timer(1, self.tick) self.timer.start()

Beobachter benachrichtig

en

Änderung

Page 95: Konzepte objektorientierter Programmierung

95

from tkinter import *

class GUIUhr(object): def __init__(self, uhr): # Referenzattribute zum Datenmodell self.uhr = uhr ... def Button_Start_Click(self): # Verarbeitung der Daten self.uhr.ticken()

def Button_Stopp_Click(self): # Verarbeitung der Daten self.uhr.stoppen()

def anzeigeAktualisieren(self): # Anzeige der Daten uhrzeit = str(self.uhr.stunden)+":"+ str(self.uhr.minuten)+":" +str(self.uhr.sekunden) self.labelUhr.config(text=uhrzeit)

Strategie: Beobachten

Beachte, dass die Klassen Uhr und GUIUhr so gestaltet sind, dass die Trennung zwischen Datenmodell und GUI weiterhin Bestand hat. Erst zur Laufzeit wird der Beobachter des Datenmodellobjekts festgelegt.

# Datenmodellfrom uhr import *uhr = Uhr()# GUI-Objektfrom guiuhr import *guiuhr = GUIUhr(uhr)# Beobachter festlegenuhr.setBeobachter(guiuhr)# Ereignisschleife startenguiuhr.fenster.mainloop()

Page 96: Konzepte objektorientierter Programmierung

96 Übungen

Aufgabe 1 (siehe www.inf-schule.de 1.12.7.8)

Die Klasse ModuloZaehler beschreibe Zähler, die modulo einer vorgegebenen Zahl zählen.

Entwickle eine einfache grafische Benutzeroberfläche, mit der man das Verhalten eines Modulo-Zählers verdeutlichen kann.

Page 97: Konzepte objektorientierter Programmierung

97 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.7.8)

Ziel ist es, ein objektorientieres Datenmodell mit einer grafische Benutzeroberfläche zu verknüpfen. Als Miniwelt betrachten wir das Spiel chuck a luck.

Page 98: Konzepte objektorientierter Programmierung

98 Übungen

Aufgabe 2 (siehe www.inf-schule.de 1.12.7.8)

Für die Benutzeroberfläche kannst du eine bereits entwickelte Implementierung übernehmen.

Implementiere das gesamte Programm so, dass eine klare Trennung zwischen Datenmodell und GUI erkennbar ist.

Page 99: Konzepte objektorientierter Programmierung

99 Teil 6

Vererbung

Page 100: Konzepte objektorientierter Programmierung

100 Sparkonto

Ein Sparkonto ist ein Konto, bei dem das eingezahlte Geld mit einem bestimmten, mit der Bank vereinbarten Zinssatz verzinst wird. Das folgende Klassendiagramm zeigt ein Sparkonto im Vergleich zu einem normalen Konto.

Aufgabe:Vergleiche die Klassendiagramme. Inwiefern unterscheiden sich die Attribute und Methoden der beiden Klassen? Überleg dir auch, ob sich bestimmte Methoden evtl. anders verhalten. Beachte, dass man das den Klassendiagrammen nicht entnehmen kann. Hinweis: Welche Regelungen gibt es bei Auszahlungen von einem Sparkonto?

Page 101: Konzepte objektorientierter Programmierung

101 Sparkonto

Ein Sparkonto kann als spezielles Konto angesehen werden, das - im Vergleich zu einem herkömmlichen Konto - nur in einigen Bestandteilen abgeändert worden ist.

Aufgabe:Wie würde man ein solches Klassendiagramm wohl lesen?

Page 102: Konzepte objektorientierter Programmierung

102 Sparkonto

Aufgabe:Analysiere die Implementierung der Klasse Sparkonto. Alles klar?Teste auch diese Implementierung.

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0 self.minimum = -1000.0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): if self.stand - betrag >= self.minimum: self.stand = self.stand - betrag else: print("Auszahlung nicht möglich!")

class Sparkonto(Konto): def __init__(self, nummer): Konto.__init__(self, nummer) self.zinssatz = None self.minimum = 0 self.maxAuszahlung = 2000.0

def setZinssatz(self, zinssatz): self.zinssatz = zinssatz

def auszahlen(self, betrag): if betrag <= self.maxAuszahlung: if self.stand - betrag >= self.minimum: self.stand = self.stand - betrag else: print("Auszahlung nicht möglich!") else: print("Auszahlung nicht möglich!")

def zinsenGutschreiben(self): zinsen = self.stand * (self.zinssatz / 100) self.einzahlen(zinsen)

Page 103: Konzepte objektorientierter Programmierung

103 Vererbung

Vererbung beschreibt die Vorgehensweise, eine neue Klasse als Erweiterung einer bereits bestehenden Klasse (oder mehrerer bereits bestehender Klassen) zu entwickeln. Die neue Klasse wird auch Subklasse genannt, die bestehende Basisklasse oder Superklasse.

Subklasse

Basisklasse / Superklasse

Übernehmen, ergänzen und überschreiben:Beim Vererben übernimmt die Subklasse die Attribute und Methoden der Basisklasse.Eine übernommene Methode kann dabei überschrieben (d. h. neu definiert) werden.Die Subklasse kann dann noch zusätzliche Attribute und Methoden ergänzen.

Page 104: Konzepte objektorientierter Programmierung

104 Implementierung in Python

class Konto(object): def __init__(self, nummer): self.nr = nummer self.stand = 0 self.minimum = -1000.0

def einzahlen(self, betrag): self.stand = self.stand + betrag

def auszahlen(self, betrag): if self.stand - betrag >= self.minimum: self.stand = self.stand - betrag else: print("Auszahlung nicht möglich!")

class Sparkonto(Konto): def __init__(self, nummer): Konto.__init__(self, nummer) self.zinssatz = None self.minimum = 0 self.maxAuszahlung = 2000.0

def setZinssatz(self, zinssatz): self.zinssatz = zinssatz

def auszahlen(self, betrag): if betrag <= self.maxAuszahlung: if self.stand - betrag >= self.minimum: self.stand = self.stand - betrag else: print("Auszahlung nicht möglich!") else: print("Auszahlung nicht möglich!")

def zinsenGutschreiben(self): zinsen = self.stand * (self.zinssatz / 100) self.einzahlen(zinsen)

Vererbung

Überschreiben

ErgänzenÜbernehmen

Page 105: Konzepte objektorientierter Programmierung

105 Übungen

Aufgabe (siehe www.inf-schule.de 1.12.7.1 und 1.12.8.5)

Auf den folgenden Folien werden verschiedene Implementierungen einer grafischen Benutzeroberfläche gezeigt.

Analysiere und erkläre, was in den jeweiligen Version unterschiedlich implementiert wird.

Page 106: Konzepte objektorientierter Programmierung

106

# Datenmodellfrom wuerfel import *wuerfel = Wuerfel()# GUIfrom tkinter import *# Ereignisverarbeitungdef Wuerfel_Click(): # Verarbeitung der Daten wuerfel.werfen() # Anzeige der Daten labelWuerfel.config(text=str(wuerfel.augen))# Erzeugung des Fenstersfenster = Tk()fenster.title("Würfel")fenster.geometry('120x110')# Eingabefeld für die ZahllabelWuerfel = Label(master=fenster, text="1", background="#FBD975")labelWuerfel.place(x=45, y=40, width=30, height=30)# Button zum AuswertenbuttonWuerfel = Button(master=fenster, text="Würfel werfen", command=Wuerfel_Click)buttonWuerfel.place(x=10, y=80, width=100, height=20)# Aktivierung des Fenstersfenster.mainloop()

Übungen

from random import randint

class Wuerfel(object): def __init__(self): self.augen = 1

def werfen(self): self.augen = randint(1, 6)

Page 107: Konzepte objektorientierter Programmierung

107

from tkinter import *

class GUIWuerfel(object): def __init__(self, wuerfel): # Referenzattribute zum Datenmodell self.wuerfel = wuerfel # Erzeugung des Fensters self.fenster = Tk() self.fenster.title("Bank") self.fenster.geometry('120x110') # Eingabefeld für die Zahl self.labelWuerfel = Label(master=self.fenster, text="1", background="#FBD975") self.labelWuerfel.place(x=45, y=40, width=30, height=30) # Button zum Auswerten self.buttonWuerfel = Button(master=self.fenster, text="Würfel werfen", command=self. Wuerfel_Click) self.buttonWuerfel.place(x=10, y=80, width=100, height=20)

def Wuerfel_Click(self): # Verarbeitung der Daten self.wuerfel.werfen() # Anzeige der Daten self.labelWuerfel.config(text=str(self.wuerfel.augen))

Übungen

# Datenmodellfrom wuerfel import *wuerfel = Wuerfel()# GUI-Objektfrom guiwuerfel import *guiwuerfel = GUIWuerfel(wuerfel)guiwuerfel.fenster.mainloop()

Page 108: Konzepte objektorientierter Programmierung

108

from tkinter import *

class GUIWuerfel(Tk): def __init__(self, wuerfel): # Referenzattribute zum Datenmodell Tk.__init__(self) self.wuerfel = wuerfel # Erzeugung des Fensters self.title("Würfel") self.geometry('120x110') # Eingabefeld für die Zahl self.labelWuerfel = Label(master=self, text="1", background="#FBD975") self.labelWuerfel.place(x=45, y=40, width=30, height=30) # Button zum Auswerten self.buttonWuerfel = Button(master=self, text="Würfel werfen", command=self.Button_Wuerfel_Click) self.buttonWuerfel.place(x=10, y=80, width=100, height=20)

def Button_Wuerfel_Click(self): # Verarbeitung der Daten self.wuerfel.werfen() # Anzeige der Daten self.labelWuerfel.config(text=str(self.wuerfel.augen))

Übungen

# Datenmodellfrom wuerfel import *wuerfel = Wuerfel()# GUI-Objektfrom guiwuerfel import *guiwuerfel = GUIWuerfel(wuerfel)guiwuerfel.mainloop()

Page 109: Konzepte objektorientierter Programmierung

109 Literaturhinweise

Es gibt eine Vielzahl von fachwissenschaftlichen Darstellungen zur objektorientierten Modellierung und Programmierung. Hier wurden folgende Lehrwerke benutzt:- D. J. Barnes, M. Kölling: Objektorientierte Programmierung mit Java. Pearson - Studium 2003.- Helmut Balzert: Lehrbuch Grundlagen der Informatik. Spektrum Ak. Verlag 1999.- Bernd Oestereich: Objektorientierte Softwareentwicklung. Oldenbourg 1998.

Dagegen gibt es nur wenige Schulbücher, die systematisch in die objektorientierte Programmierung einführen, z. B.: - Siegfried Spolwig: Objektorientierung im Informatikunterricht. Dümmler-Verlag 1997.- P. Damann, J. Wemßen: Objektorientierte Programmierung mit Delphi, Band 2. Klett-Verlag 2003.

Viele interessante Artikel mit Unterrichtsvorschlägen bzw. fachdidaktischen Auseinandersetzungen findet man in der Zeitschrift LOG IN. Das Themenheft 128/129 ist speziell dem Thema „Objektorientiertes Modellieren und Programmieren“ gewidmet.

...

Page 110: Konzepte objektorientierter Programmierung

110 Literaturhinweise

Im Internet findet man ebenfalls sehr viele schulgerechte Darstellungen der objektorientierten Modellierung und Programmierung, z. B:

http://informatikag.bildung-rp.de/ Die AG-Informatik des LMZ in RLP stellt u. a. auch Fortbildungsmaterialien zu diesem Thema bereit.

http://hsg.region-kaiserslautern.de/faecher/inf/index.php Auf der Homepage des HSG in Kaiserslautern findet man Unterrichtsmaterialien und Links zu weiteren interessanten Seiten.

...

Die Darstellung hier orientiert sich an den Materialien auf den Webseiten:

http://www.inf-schule.de