54
Kapitel 8: Klassen und Objekte Grundlagen der Programmierung 1 Holger Karl Wintersemester 2018/2018 Inhaltsverzeichnis Inhaltsverzeichnis 1 Abbildungsverzeichnis 2 Liste von Definitionen u.ä. 3 8.1 Überblick ............................... 4 8.2 Zusammenhang von Daten und Funktionen ........... 4 8.3 Klassen ................................ 6 8.4 Objekte/Instanzen .......................... 8 8.5 Definition und Instantiierung einer Klasse ............ 10 8.6 Definition und Aufruf weiterer Methoden ............. 20 8.7 Statische Attribute und Methoden ................. 28 8.8 Beobachtungen ........................... 36 8.9 Beispiele ............................... 39 1

Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

  • Upload
    doantu

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

Kapitel 8: Klassen und ObjekteGrundlagen der Programmierung 1

Holger Karl

Wintersemester 2018/2018

Inhaltsverzeichnis

Inhaltsverzeichnis 1

Abbildungsverzeichnis 2

Liste von Definitionen u.ä. 38.1 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48.2 Zusammenhang von Daten und Funktionen . . . . . . . . . . . 48.3 Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68.4 Objekte/Instanzen . . . . . . . . . . . . . . . . . . . . . . . . . . 88.5 Definition und Instantiierung einer Klasse . . . . . . . . . . . . 108.6 Definition und Aufruf weiterer Methoden . . . . . . . . . . . . . 208.7 Statische Attribute und Methoden . . . . . . . . . . . . . . . . . 288.8 Beobachtungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 368.9 Beispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

1

Page 2: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.10 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . 53

Abbildungsverzeichnis

8.1 Ein Beispiel für die Eigenschaften einer Ellipse . . . . . . . . . . 68.2 Eine Klasse für Ellipsen . . . . . . . . . . . . . . . . . . . . . . 78.3 Instanz der Ellipsen-Klassen . . . . . . . . . . . . . . . . . . . 98.4 Anlegen der Klasse selbst . . . . . . . . . . . . . . . . . . . . . 128.5 Instantiieren des Objekts; zu Beginn der Ausführung des Kon-

struktors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138.6 Instatiieren des Objekts; Anlegen des ersten Attributes . . . . . 138.7 Instantiieren des Objektes: Alle Attribute erzeugt, Konstruktor

unmittelbar vor Ende . . . . . . . . . . . . . . . . . . . . . . . . 148.8 Instantiieren des Objektes: Nach Ende des Konstruktors . . . . 158.9 Instantiieren des Objektes: Nach Ende des Konstruktors, kom-

pakte Darstellung . . . . . . . . . . . . . . . . . . . . . . . . . . 158.10 Drei Ellipsen-Objekte . . . . . . . . . . . . . . . . . . . . . . . . 178.11 Drei Ellipsen-Objekte, kompakt . . . . . . . . . . . . . . . . . . 188.12 Attribute der Klasse: Methoden und docstring . . . . . . . . . . 218.13 Erweiterung des Attribute-dict um weitere Namen/Werte . . . . 318.14 Statische vs. dynamische Attribute: Anlegen der Klasse selbst . 318.15 Statische vs. Objektattribute: Anlegen von c1 . . . . . . . . . . 328.16 Statische vs. Objektattribute: Anlegen von c2 . . . . . . . . . . 338.17 Eine Stack-Klasse als UML-Diagramm . . . . . . . . . . . . . . 408.18 Ellipse delegiert an Punkt . . . . . . . . . . . . . . . . . . . . . 448.19 Ellipse delegiert an Punkt, kompakte Darstellung . . . . . . . . 458.20 Eine Telefonbuch-Klasse als UML-Diagramm . . . . . . . . . . 468.21 Ein binärer Suchbaum . . . . . . . . . . . . . . . . . . . . . . . 488.22 Suchbaum und Knoten als UML-Diagramm . . . . . . . . . . . 498.23 Einfügen in einen binärer Suchbaum . . . . . . . . . . . . . . . 52

2

Page 3: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.24 Begriffsüberlick der wesentlichen Begriff zu Klassen . . . . . . 54

Liste von Definitionen u.ä.

8.1 Definition (Klasse) . . . . . . . . . . . . . . . . . . . . . . . . . 78.2 Definition (Objekt (oder Instanz)) . . . . . . . . . . . . . . . . 88.1 Bemerkung (Objekt einer Klasse) . . . . . . . . . . . . . . . . . 88.3 Definition (Vordefinierte Namen) . . . . . . . . . . . . . . . . . 20

3

Page 4: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

4 Liste von Definitionen u.ä.

8.1 Überblick

8.1.1 Was bisher geschah

• Datenstrukturen– Einfach: Zahlen, Wahrheitswerte– Zusammengesetzt: Zeichenketten, Listen, Tuple, Sets, Dicts

• Programmstrukturen– Schleifen, Verzweigung– Funktionen: Definition und Aufruf

8.1.2 Dieses Kapitel

• Wir erweitern die Vorstellung zusammengesetzter Datenstrukturen– Definition und Nutzung eigener Strukturen– Angepasst an Bedarf des Programms

• Formalisiert als Klassen (classes)

8.2 Zusammenhang von Daten und Funktionen

8.2.1 Sammlung von Daten

• Zusammengesetzte Datenstrukturen erlauben das Sammeln zusammen-gehöriger Daten– Listen, Tuple: Zugriff durch Index– Dicts: Zugriff durch Name

• Mit einfacher Funktionalität– Anzahl Elemente– Anfügen, Entfernen, Suchen, . . .

• Aber: Generisch– Eigene Funktionen?

8.2.2 Daten und Funktionen

• Datenstruktur be-/verarbeiten: Anwendungsspezifische Funktionen be-nötigt

• Beispiele:– Anmeldungen zur Vorlesung GP1 verwalten (in PAUL)– Liste der Klausurnoten manipulieren

Page 5: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.2. Zusammenhang von Daten und Funktionen 5

– in einem Grafikprogramm: Funktionen, um Kreise zu malen, ver-schieben, verändern, . . .

– Kontoverwaltung einer Bank• Gemeinsamkeit: Spezifische Daten mit spezifischen Funktionen bear-beiten

8.2.3 Spezifische Daten, spezifische Funktion

• Wie würde man das implementieren?• Klassisch:

– Wir beschreiben die Datenstruktur, z.B. als dict und list, Listevon Dicts, etc.

– Wir schreiben separat Funktionen dazu auf

8.2.4 Frage: Zusammenhang?

• Woher weiß man, dass– bestimmte Daten durch bestimmte Funktionen verarbeitet werdenmüssen?

– bestimmte Funktionen nur sinnvoll auf bestimmte Daten ange-wandt werden können?

• Optionen?– Namenskonvention? Für die Funktionen?– Im Programmcode nahe beinander aufschreiben?

• Nicht überzeugend!

8.2.5 Zusammenhang explizit?

• Übliches Argument: Häufiger Fall verdient Unterstützung durch Pro-grammiersprache!

• Wunschvorstellung: Ein Konstrukt, das erlaubt:– Datenstruktur zu beschreiben– Zugehörige Funktionen zu definieren

* Funktionen, die diese Daten be-/verarbeiten können• Grobe Analogie: Eine Art dict dem man Funktionen hinzufügen kann

8.2.6 Beispiel: Ellipse in einem Zeichenprogramm

• Kontext: Ein 2D-Zeichenprogramm• Was braucht man, um eine Ellipse zu beschreiben?

– Ort– Die beiden Achsen– Randfarbe, Strichdicke, . . .– Füllfarbe, Schraffur, . . .

• Was macht man mit einer Ellipse?

Page 6: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

6 Liste von Definitionen u.ä.

– Verschieben– Verzerren– Drehen– Auf Sonderfälle testen: Ist es ein Kreis?– . . .

8.2.7 Beispiel: Ellipse

Abbilidung 8.1 zeigt eine gefärbte, gedrehte und verschobene Ellipse.

Abbildung 8.1: Ein Beispiel für die Eigenschaften einer Ellipse

8.3 Klassen

8.3.1 Klassen

• Eine Klasse (class) dient dazu, zusammengehörende Daten und Funk-tionen zusammen aufzuschreiben– (Plus weitere Eigenschaften; siehe später)– Klasse beschreibt die Struktur, ist ein Bauplan

8.3.2 Kreis als Klasse: Graphische Notation

Abbildung 8.2 zeigt ein sog. UML-Diagramm für eine Klasse. UML steht fürUnified Modelling Language und ist eine Standard-Notation für Klassen (undObjektorientierung im allgemeinen; siehe später).

Page 7: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.3. Klassen 7

Abbildung 8.2: Eine Klasse für Ellipsen

Eine Klasse wird in UML als eine Box mit drei Teilen gezeichnet: Im erstenTeil der Name der Klasse, dann eine Auflistung der Daten, die zu der Klassegehörten. Im dritten Teil die Funktionen, die diese Daten manipulieren.

8.3.3 Klasse: Definition

Definition 8.1 (Klasse). Eine Klasse definiert einen Bauplan für gleichartigeObjekte. Sie beschreibt in einer kompakten, zusammenhängenden Form

• Datenelemente (auch: Attribute, Felder, fields) und• Operationen auf diesen Daten (auch:Methoden, methods)

8.3.4 Klassen – Notation in Python

• Wir brauchen ein neues Schlüsselwort: class– class erzeugt (ähnlich zu def) einen neuen Block, in dem dieMethoden und Daten aufgeführt werden

– In diesem Block dürfen Anweisungen stehen• Einfachstes Beispiel: Eine Klasse ohne Daten, ohne Operationen

– Anmerkung: pass ist syntaktisch notwendig; es darf keinen leerenBlock geben. pass ist die Anweisung, die nichts tut.

1 class Ellipse:2 pass

8.3.5 Konventionen

Namenskonventionen:

Page 8: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8 Liste von Definitionen u.ä.

• Klassennamen beginnt mit Großbuchstaben• Methoden, Attribute klein

– wie Funktionsnamen und sonstige Namen auch• Methoden oft ein Verb: etwas tun!

8.4 Objekte/Instanzen

8.4.1 Klassen und Instanzen

• Eine Klasse ist aber zunächst kein nutzbarer Wert• Wir nutzen den Bauplan, um einen entsprechenden Wert zu erhalten

– Wir instantiieren die Klasse um ein Objekt (eine Instanz) der Klassezu erzeugen

8.4.2 Erzeugen eines Objektes

• Typischerweise werden bei Objekterzeugung Anfangswerte an das zuerzeugende Objekt übergeben

• Diese Anfangswerte werden durch eine spezielle Methode der Klasseverarbeitet, den Konstruktor– In Python, per Konvention: __init__

• Der Konstruktur nimmt die Anfangswerte und befüllt damit die Attributeder Klasse

8.4.3 Objekte: Definition

Definition 8.2 (Objekt (oder Instanz)). EinObjekt (oder Instanz) einer Klasseist eine konkrete Ausprägung des durch eine Klasse vorgegebenen Bauplans.Ein Objekt enthält bestimmte Werte. Ein Objekt führt den Code nur auf Auf-forderung aus.

Die Begriffe Objekt und Instanz sind weitgehend austauschbar.

Bemerkung 8.1 (Objekt einer Klasse). EinObjekt oder eine Instanz ist immerauf eine bestimmte Klasse bezogen. Es ist (streng genommen) sinnlos, voneinem Objekt ohne Bezug auf seine Klasse zu reden.

Page 9: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.4. Objekte/Instanzen 9

8.4.4 Objekte/Instanzen: Graphische Notation

Eine Instanz einer Klasse wird in UML ähnlich notiert wie eine Klasse – Ab-bildung 8.3 zeigt ein Beispiel. Im Unterschied zur Klasse wird im Kopf derName des Objekts zusätzlich zum Namen der Klasse angegeben. Im zweitenAbschnitt werden die jeweils spezifischen Werte der Attribute aufgeführt (hiernur ein paar Beispiele für eine Ellipse).

Abbildung 8.3: Instanz der Ellipsen-Klassen

8.4.5 Objekt: Zugriff auf die eigenen Attribute?

• Die Methoden einer Klasse werden wir wohl ähnlich wie Funktionen mitdef aufschreiben (es sind schließlich Funktionen)

• Eine solcheMethode hat einen Namensraum – analog bei einemObjekt?– Sicherlich evtl. vorhandene Parameter der Methode, evtl. globaleNamen

– Zusätzlich: die Attribute des Objektes selbst!• Idee: Objekte definieren einen Namensraum

– Ähnlich wie Funktionen

8.4.6 Objekt: Notation

• Zugriff auf eigene Attribute ist wichtiger Fall, sollte im Code deutlichsichtbar sein

• Konvention in Python: Einem Attribute wird self. vorangestellt– Signalisiert: Zugriff auf Attribut des Objektes!

8.5 Definition und Instantiierung einer Klasse

Page 10: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

10 Liste von Definitionen u.ä.

8.5.1 Konstruktur

Fangen wir mit dem Konstruktur der Klasse Ellipse an:

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a2

8.5.2 Konstruktor – Struktur

• Innerhalb der Klasse vereinbaren wir eine Methode mit def– Offenbar soll das bedeuten, dass diese Methode eine Funktion ist,die zu dieser Klasse gehört

• Der Name dieser Methode ist __init__– Und damit per Konvention der Konstruktor – der muss so heißen

* In Python – andere Sprachen haben andere Konventionen– Der Konstruktor wird beim Instanziieren eines Objektes aufgerufen(mehr gleich)

8.5.3 Konstruktor – Struktur (2)

• Diese Methode hat fünf Parameter:– Den besonderen Parameter self: repräsentiert das Objekt selbst– x und y für denMittelpunkt, a1 und a2 für die beiden Achsen einerEllipse

• Die Methode __init__ kopiert die letzen vier Parameter in Attributedes Objektes– Attribut des Objekts: Erkennbar durch das Voranstellen von self.(der Punkt ist wichtig)!

– Die Namen der Parameter und der Attribute müssen nicht gleichsein

– Kann aber praktisch sein, ähnliche Namen zu nutzen – Dokumen-tation!

8.5.4 Instanziieren und Konstruktoraufruf

• Wann wird diese Methode nun aufgerufen?• Beim Instanziieren eines Objektes!

Page 11: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.5. Definition und Instantiierung einer Klasse 11

• Notation: den Klassennamen wie einen Funktionsnamen nutzen– Und mit Parametern für __init__ versorgen

1 e1 = Ellipse(1, 2, 17.5, 0.4)

8.5.5 Klassen sind Typen

• Die Notation zur Instatiierung ist vertraut• Das entspricht etwa der Definition einer Liste, eines Sets, o.ä.

– Das waren Typen– Ist eine Klasse also ein neuer Typ?

Ja!

• Klassen definieren einen neuen Datentyp• Kann überall verwendet werden, wo auch sonst ein Typ verwendet wer-den kann

8.5.6 Nur vier Parameter?

• Müssten das nicht fünf Parameter sein? Was ist mit demWert für self?• Überlegung: self kann man beim Erzeugen des Objekts gar nicht ange-ben; das Objekt gibt es ja noch nicht– Also kann man das auch nicht von Hand an den Konstruktor über-geben

– Das muss die Programmiersprache (der Interpreter) von alleineerledigen!

8.5.7 Instanziieren und Konstruktoraufruf (2)

Was passiert also beim Erschaffen eines Objektes?

1. Beim Aufruf des Klassennamens wird Speicherplatz für das Objekt ange-legt

2. Eine Referenz auf diesen Speicherplatz entsteht3. Der Konstruktur wird aufgerufen mit

a) Dieser Referenz als Wert für den Parameter selfb) Der restlichen Wert für die anderen Parameter

4. Der Konstruktur wird wie eine normale Funktion ausgeführta) Mit der zusätzlichen Besonderheit, dass durch self. Attributeinnerhalb des Objektes zugegriffen werden kann

Page 12: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

12 Liste von Definitionen u.ä.

8.5.8 Konstruktor – Ablaufbeispiel

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 e1 = Ellipse(1, 2, 17.5, 0.4)

(PT link)

Visualisierung

Gehen wir diesen Ablauf Schritt für Schritt durch.

1. Anlegen des Namens EllipseIm ersten Schritt wird die Anweisung class ausgeführt. Es ist eineAnweisung ähnlich wie def, d.h., sie vereinbart einen Namen (hier: El-lipse) der auf eine Klasse zeigt. Diese Klasse ist in diesemBeispiel nochsehr bescheiden – sie hat lediglich eine einzige Methode __init__.Abbildung 8.4 zeigt diesen Zustand.

Abbildung 8.4: Anlegen der Klasse selbst

2. Erzeugen des Objekts, Aufruf des KonstruktorsIm nächsten Schritt (Abbildung 8.5), mit der Ausführung der Zeile 8,beginnt der Aufruf des Konstruktors. Hier wurde bereits das Objektan sich angelegt – im rechten Teil als Ellipse instance zu sehen.Allerdings ist dieses Objekt noch leer (es hat noch keine Attribute) undist somit nur als eine einzelne Zeile dargstellt.Die __init__-Methode wird – wie jede andere Funktion auch – beimAufruf mit einem eigenen Namensraum versehen. In diesem Namens-raum sind die fünf Parameter. Der self Parameter ist eine Referenzauf das gerade neu angelegte Objekt (siehe rechts: self hat einen Pfeilauf Ellipse instance). Die vier anderen Parameter zeigen (ganznormal) auf die entsprechenden Werte.

Page 13: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.5. Definition und Instantiierung einer Klasse 13

Abbildung 8.5: Instantiieren des Objekts; zu Beginn der Ausführung desKonstruktors

3. Erzeugen des ersten AttributesSobald die Zeile 3 ausgeführt wurde (Abbildung 8.6), wurde das erste At-tribut (der Name x) im Ellipse-Objekt angelegt. In Ellipse instanceist ein Pfeilpaar entstanden; der erste Pfeil weisst auf den String x – denNamen des Attributes – der zweite Pfeil auf den Wert 1. Natürlich zeigtauch der Parameter x auf den Wert 1.

Abbildung 8.6: Instatiieren des Objekts; Anlegen des ersten Attributes

Aber entsteht jetzt hier nicht ein Problem? Haben wir jetzt nicht zweiverschiedene x im Spiel? Nein, eigentlich nicht! Es gibt einmal den Para-meter x der Methode __init__; dieses x lebt (wie bei jeder Funktion)imNamensraumdieserMethode. Das anderex ist das Attribut des geradeangelegten Objektes; dieses x existiert in einem anderen Namensraum,nämlich dem Objekt-Namensraum. Um auf diesen Namensraum zuzu-greifen, brauchen wir self – self.x ist also eine Notation, die denZugriff auf Namen in einem anderen Namensraum erlaubt!Beobachten Sie hier auch die Ähnlichkeit der Darstellung zu dict-

Page 14: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

14 Liste von Definitionen u.ä.

Objekten: auch diese sind durch solche Pfeilpaare repräsentiert. Tat-sächlich sind dict und die Attribute eines Objektes recht eng verwandt;typischerweise werden die Attribute einfach in einem dict gespeichert!Sie unterscheiden sich hauptsächlich durch die Notation:• Bei dict d wird auf die einzelnen Einträge durch eckige Klammerzugegriffen d[’x’]

• Bei einem Objekt, das durch self referenziert wird, reicht dieeinfachere Notation self.x

Dies hat vor allem historische Gründe und Gründe in der Analogie zuanderen Sprachen. Sie sollten diesen notationellen Unterschied nichtüberbewerten; das muss man sich einfach merken.

4. Erzeugen aller AttriubuteNachdem Zeile 6 ausgeführt wurde (Abbildung ??) sind die weiteren At-tribute y, achse1 und achse2 im Namensraum self erzeugt worden.Beachten Sie hier den return-Wert der __init__-Methode: das istNone, der nicht vorhandene Wert.

Abbildung 8.7: Instantiieren des Objektes: Alle Attribute erzeugt, Konstruktorunmittelbar vor Ende

5. Nach Ende des KonstruktorsNachdem dem Ende des Konstruktors __init__ zeigt der Name e1 aufdas gerade erzeugte und durch den Konstruktor mit Attributen befüllteObjekt (Abbildung 8.8).Das ist eigentlich etwas seltsam: Der Konstruktor hatte doch None alsRückgabewert? Wäre es nicht plausibler, hier ein return self am

Page 15: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.5. Definition und Instantiierung einer Klasse 15

Abbildung 8.8: Instantiieren des Objektes: Nach Ende des Konstruktors

Ende des Konstruktors zu fordern?Möglicherweise wäre dies konsistenter mit der Erwartungshaltung beiFunktionen. Allerdings ist dieser Fall so häufig, dass die Sprachkonven-tion bei Python ist, bei einem Konstruktor keine return-Anweisungvorzusehen (oder nur ein return None). Die Zuweisung des erzeugtenObjektes an den Namen e1 erfolgt implizit.Zur besseren Übersichtlichkeit in Abbildung 8.9 noch die kompakteDarstellung des Endzustandes (inhaltlich äquivalent zu Abbildung 8.8 ).

Abbildung 8.9: Instantiieren des Objektes: Nach Ende des Konstruktors, kom-pakte Darstellung

8.5.9 Beobachtung: self ist ein Namensraum!

• Bei Ausführung des Konstruktors sind zwei Namensräume im Spiel

Page 16: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

16 Liste von Definitionen u.ä.

– Der übliche Namensraum des Konstruktors als Funktion: x, y, a1,a2 und insbesondere self

– Der durch self erreichbare Namensraum des Objekts

8.5.10 Instantiierung weiterer Objekte

• Instantiieren wir als Beispiel zwei weitere Instanzen der Klasse

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 e1 = Ellipse(1, 2, 17.5, 0.4)9 e2 = Ellipse(0, -5, 3, 1)10 e3 = Ellipse(17, 18, 19, 20)

(PT link)

Visualisierung

Die Visualierung durch pythontutor ist in Abbildung 8.10 zu sehen:

• Drei Namen e1, e2, e3 referenzieren drei Objekte der Klasse Ellipse• Diese drei Objekte haben jeweils die gleichen Attribute; diese Attribut-namen referenzieren jeweils die gleiche Werte

• Die Attributwerte hingegen sind je nach Objekt unterschiedlich

Page 17: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.5. Definition und Instantiierung einer Klasse 17

Abbildung 8.10: Drei Ellipsen-Objekte

Page 18: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

18 Liste von Definitionen u.ä.

Auch hier (Abbildung 8.11) noch die kompakte Darstellung des gleichen Zu-stands.

Abbildung 8.11: Drei Ellipsen-Objekte, kompakt

8.5.11 Flexible Konstruktoren

• Parameter eines Konstruktors sind Parameter einer Funktion• Also kann man hier die flexiblen Techniken für Funktionsparametereinsetzen!– Default-Werte für optionale Parameter– Variable Anzahl von Parametern (*args)– Schlüsselwort-Parameter (**kwargs)

• Konstruktor inspiziert seine Parameter und verhält sich entsprechend

8.5.12 Flexible Konstruktoren – Beispiel Ellipse

• Eine Ellipse mit nur einem Radius ist ein Kreis:

1 class Ellipse:2 def __init__(self, x, y, a1, a2=None):3 self.x = x4 self.y = y5 self.achse1 = a16 if a2:7 self.achse2 = a28 else:9 self.achse2 = a110

11 e1 = Ellipse(1, 2, 17.5)

Page 19: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.5. Definition und Instantiierung einer Klasse 19

(PT link)

<__main__.Ellipse object at 0x1010789b0>

8.5.13 Unterschiede zu anderen Sprachen: Dynamische Attribute

Wenn Sie mit anderen Sprachen (wie Java o.ä.) vertraut sind, wird es Ihnenvielleicht seltsam vorkommen, dass wir keine Attribute an sich vereinbarenmussten bei der Definition der Klasse. Das stimmt – in Python werden Attribu-te dynamisch festgelegt. Das funktioniert auch ausserhalb eines Konstruktors.

8.5.14 Dokumentation einer Klasse: docstring

• Erinnerung: docstring einer Funktion

1 def complex(real, imag):2 """Form a complex number.3

4 Keyword arguments:5 real -- the real part6 imag -- the imaginary part7 """8

9 # Und hier würden Anweisungen folgen

Für Klassen?

• Dokumentation einer Klasse durch docstrings?

8.5.15 docstring für Klasse

• Analog zu Funktion: Folgt nach dem class-Ausdruck ein String, sowird dieser zum docstring der Klasse

• Ist als vordefiniertes Attribut __doc__ eines Objektes zugreifbar• Auch: Vordefiniertes Attribut des Klassennamens selbst

1 class Ellipse:2 """Eine Ellipsen-Klasse implementiert Datenstruktur und Verhalten3 einer Ellipse."""4

5 def __init__(self, x, y, a1, a2):6 self.x = x

Page 20: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

20 Liste von Definitionen u.ä.

7 self.y = y8 self.achse1 = a19 self.achse2 = a210

11 e1 = Ellipse(1, 2, 17.5, 9.3)12 print(e1.__doc__)13 print(Ellipse.__doc__)

8.5.16 Konvention: Paare von Unterstrichen

Definition 8.3 (Vordefinierte Namen). Vordefinierte Namen sind durch __-Paaremarkiert. SolcheNamen sollten nicht im eigenemCode definiert werden!

8.5.17 Beispiele für weitere vordefinierte Attribute

• Neben __init__, __doc__ existieren weitere vordefinierte Attributefür Klassen

• Beispiele:– __name__ : Der Name einer Funktion oder einer Klasse– __dict__ : Das dict-Objekt, in dem die Attribute abgelegt sind

8.6 Definition und Aufruf weiterer Methoden

8.6.1 Weitere Methoden

Weitere Methoden eines Objektes werden analog zu __init__ vereinbart:

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 def verschiebe(self, deltax, deltay):9 self.x += deltax10 self.y += deltay11

Page 21: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.6. Definition und Aufruf weiterer Methoden 21

12 def istKreis(self):13 return self.achse1 == self.achse2

Visualisierung

Es lohnt sich, hier die Visualisierung zu betrachten, obwohl nur eine einzigeAnweisung ausgeführt wird: die Anweisung class, die den Namen Ellipsedefiniert. Während dieser Anweisung passieren allerdings mehrere Dinge:Die Namen __init__, verschiebe und istKreis für die drei Methodenwerden erzeugt und mit den entsprechenden Funktionen verbunden.

Diese drei Namen gehören zur Klasse und müssen im Attribute- dict derKlasse abgelegt werden. Abbildung 8.12 illustriert dies: Im Attribute- dictder Klasse werden diese drei Namen mit den entsprechenden Funktionenverbunden.

Abbildung 8.12: Attribute der Klasse: Methoden und docstring

8.6.2 Weitere Methoden: Auf self achten!

• Achten Sie bei der Vereinbarung einerMethode auf den ersten Parameterself

• Ohne diesen haben Sie keinen Zugriff auf denNamensraumdesObjektes,können also die Attribute nicht benutzen!

8.6.3 Aufruf von Methoden

• Methoden sind auch nur Attribute eines Objekts!• Also durch Punkt . ausgewählt

– Ähnlich wie bei self in einer Methode• Beispiel:

Page 22: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

22 Liste von Definitionen u.ä.

1 class Simple:2 def f(self):3 print("f aufgerufen")4

5 s = Simple()6 print(s.f)

<bound method Simple.f of <__main__.Simple object at 0x10c673240>>

Beobachtung

• s.f ist nur ein Name für eine Methode (als Funktion innerhalb einesObjekts)

• Nebenbei: eine Klasse braucht kein __init__!

8.6.4 Aufruf von Methoden (2)

• Wir müssen s.f also noch aufrufen!• Aufruf wie gewohnt durch ()• Beispiel:

1 class Simple:2 def f(self):3 print("f aufgerufen")4

5 s = Simple()6 print(s.f)7 s.f()

<bound method Simple.f of <__main__.Simple object at 0x10f3d8240>>f aufgerufen

8.6.5 Methodenaufruf – Sprechweise

• Eine Vorstellung (bisher benutzt): Methoden sind Funktionen, die auf-gerufen werden können

• Andere Vorstellung:– An ein Objekt können Nachrichten geschickt werden– Nachrichten haben Namen (und tragen ggf. Daten)– Die Namen der Nachrichten entsprechen den Methodennamen– Empfängt ein Objekt eine Nachricht, so wird diese durch den Codeentsprechender Methode verarbeitet

Page 23: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.6. Definition und Aufruf weiterer Methoden 23

– Nachrichten mit unbekanntem Namen werden ignoriert• Weitgehend äquivalente Vorstellungen

– Historie Nachrichten: Smalltalk

8.6.6 Was passiert bei Aufruf?

• Auch hier stimmen die Parameter wieder nicht?– Ähnlich wie oben bei __init__?

• f wird mit einem Parameter self vereinbart, beim Aufruf wird aberkein Wert übergeben?– Doch!– Als Wert für den Parameter selfwird eine Referenz auf das Objektübergeben, bei dem die Funktion aufgerufen wurde!

8.6.7 Was passiert bei Aufruf? – Kurzschreibweise!

• Tatsächlich ist s.f() nur eine Kurzschreibweise• Ausführlich könnte man schreiben:

– Simple.f(s)• Das bedeutet:

– Nimm die Klasse Simple– Davon die Funktion f, die ja einen Parameter erwartet– Rufe diese Funktion auf und übergebe eine Referenz auf das Objekts an den Parameter self

• Und damit ist das eigentlich ein ganz normaler Funktionsaufruf!!!

8.6.8 Was passiert bei Aufruf? – Kurzschreibweise auflösen

1 class Simple:2 def f(self):3 print("f aufgerufen mit Objekt:", self)4

5 s = Simple()6 s.f()7 Simple.f(s)

f aufgerufen mit Objekt: <__main__.Simple object at 0x109165240>f aufgerufen mit Objekt: <__main__.Simple object at 0x109165240>

8.6.9 Konventionen für weitere Methoden

• __init__ ist eine Konvention für die Konstruktor-Methode• Python sieht eine Reihe weiterer Konventionen vor:

Page 24: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

24 Liste von Definitionen u.ä.

– Eine Methode __str__(self) erzeugt eine Text-Repräsentationeines Objekts* Wird automatisch aufgerufen, wenn ein String gebraucht wird,z.B. für print

– Methode __eq__(self, other) vergleicht das Objekt self miteinem anderen Objekt other der gleichen Klasse und entscheidet,ob die beiden Objekte gleich sind* Inhaltliche Gleichheit; nicht Identität

– Analog: __lt__, __le__, usw.• Siehehttps://docs.python.org/3/reference/datamodel.html,Abschnitt 3.3, für Details

8.6.10 Gleichheit?

• Gleichheit der Referenz/Identität: Zwei Namen referenzieren das identi-sche Objekt– Durch is getestet– Auch durch == falls kein __eq__

• Inhaltliche Gleichheit: Eine Klasse kann beliebig definieren, wann zweiunterschiedliche Objekte als gleich angesehen werden sollen– Hinreichend ähnlich, kongruent, . . . je nach Anwendung– Durch __eq__ realisiert, durch == benutzt falls vorhanden

8.6.11 Gleichheit – Beispiel ohne eq

Ohne __eq__:

• Nur Vergleich referenziert gleiches Objekt zwischen Namen• Kein Unterschied zwischen == und is

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 e1 = Ellipse(0, 1, 2, 3)9 e2 = e110 e3 = Ellipse(0, 1, 2, 3)11

12 print("==:")13 print(e1 == e2)14 print(e1 == e3)

Page 25: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.6. Definition und Aufruf weiterer Methoden 25

15 print(e2 == e3)16

17 print("is:")18 print(e1 is e2)19 print(e1 is e3)20 print(e2 is e3)

8.6.12 Gleichheit – Beispiel mit eq

Mit __eq__:

• == ruft __eq__ auf und macht inhaltlichen Vergleich• is wie oben: Referenziert gleiches Objekt?

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 def __eq__(self, otherEllipse):9 return (10 self.x == otherEllipse.x and11 self.y == otherEllipse.y and12 self.achse1 == otherEllipse.achse1 and13 self.achse2 == otherEllipse.achse214 )15

16 e1 = Ellipse(0, 1, 2, 3)17 e2 = e118 e3 = Ellipse(0, 1, 2, 3)19

20 print("==:")21 print(e1 == e2)22 print(e1 == e3)23 print(e2 == e3)24

25 print("is:")26 print(e1 is e2)27 print(e1 is e3)28 print(e2 is e3)

Page 26: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

26 Liste von Definitionen u.ä.

(PT link)

TrueTrueTrueis:TrueFalseFalse

8.6.13 Fallstricke bei eq

• Möglicher Fallstrick: Objekt einer Klasse C1 hat Referenzen auf andereObjekte einer Klasse C2

• In C1.__eq__: wie mit Referenzen auf C2 umgehen?– Lediglich die C2-Referenzen vergleichen?– Oder sollte C2 selbst ein __eq__ haben?– Anders gesagt: nimmt man is oder == für die C2-Objekte?

1 class C2:2 pass3

4 class C1:5 def __init__(self):6 self.x = 427 self.c2 = C2()8

9 def __eq__(self, otherC1):10 return ((self.x == otherC1.x) and11 (self.c2 == otherC1.c2))12

13 c1a = C1()14 c1b = C1()15

16 print(c1a is c1b)

False

Pingo

1 pingo_title = "c1a is c1b? "2 pingo_questions = ["Wahr", "Falsch", "True", "False"]

Page 27: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.6. Definition und Aufruf weiterer Methoden 27

3

4 %pingo

8.6.14 Ellipse – mit str

1 class Ellipse:2 def __init__(self, x, y, a1, a2):3 self.x = x4 self.y = y5 self.achse1 = a16 self.achse2 = a27

8 def __str__(self):9 return ("Ellipse at ({},{}) with axes {},{}".10 format(self.x, self.y,11 self.achse1, self.achse2))12

13 def verschiebe(self, deltax, deltay):14 self.x += deltax15 self.y += deltay16

17 e = Ellipse(0, 1, 2, 3)18 print(e)19 e.verschiebe(-2, +5)20 print(e)

8.6.15 Flexible Methoden

• Ähnlich zu Konstruktoren: Wie gehen wir mit Methoden um, die ei-gentlich das gleiche tun, aber eine unterschiedliche Anzahl Parameterhaben?

• Optionen:– Mehrere Methoden mit gleichem Namen definieren, mit unter-schiedlicher Parameterzahl?* Nein, funktioniert nicht* (Häufiger Ansatz in anderen Sprachen)

– Flexible Parameter nutzen: defaults, *args, **kwargs* Deutlich übersichtlicher; Code bleibt an einer Stelle gesammelt

Vergleich mit anderen Sprachen

Wenn Sie mit Sprachen C++ oder Java bereits vertraut sind, würden Sie andieser Stelle möglicherweise eine Diskussion über überladene Methoden er-

Page 28: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

28 Liste von Definitionen u.ä.

warten. Dies ist in einer dynamisch typisierten Sprache wie Python allerdingskein sinnvolles Konzept; man könnte lediglich auf die Anzahl der Parame-ter zurückgreifen, was wenig hilfreich ist. Daher gibt es keine überladenenMethoden in Python.

Wir kommen darauf bei der Besprechung von Java nochmals zurück.

8.7 Statische Attribute und Methoden

8.7.1 Aufruf von Methoden bei Objekten

• Wir haben die Äquivalenz dieser beiden Anweisungen oben diskutiert:

1 Simple.f(s)2 s.f()

Beobachtung

• Offenbar definiert also eine Klasse einen Namensraum, in dem Funkti-onsnamen zugreifbar sind

• Bisher haben wir in diesem Namensraum nur Methoden vereinbart, dieself als ersten Parameter haben

• Was, wenn kein self?

8.7.2 self-lose Methoden

• Ist so etwas denkbar? Was wäre die Semantik?

1 class C:2 def f():3 print("Methode ohne self")4

5 c1 = C()6 print(c1)

<__main__.C object at 0x103ebc4e0>

Page 29: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.7. Statische Attribute und Methoden 29

Offenbar möglich

• Offenbar kann so eine Klasse definiert und instanziiert werden• Aber was ist mit f? Aufruf?

8.7.3 self-lose Methoden: Aufruf

• Aufruf einer self-losen Methode bei Objekt?

1 class C:2 def f():3 print("Methode ohne self")4

5 c1 = C()6 c1.f()

Aufruf scheitert

• Fehlermeldung:TypeError: f() takes 0 positional argumentsbut 1 was given

• Das ist plausibel!– Definition des Methodenaufrufs sagt ja, dass c1.f() das gleicheist wie C.f(c1)

– Aber f nimmt keinen Parameter entgegen; das kann nicht gehen

8.7.4 self-lose Methoden – Aufruf nur bei Klasse?

• Wie wäre es mit Aufruf nur über die Klasse selbst?

1 class C:2 def f():3 print("Methode ohne self aufgerufen")4

5 C.f()

Das geht!

• Offenbar möglich: Die Funktion f wird als ganz normale Funktion aus-geführt – ohne den Namensraum eines Objekts!

• Aber dann hat f keinen Zugriff auf Attribute!?– Die existieren ja im Namensraum eines jeden Objektes, separat

• Ist das nützlich?

Page 30: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

30 Liste von Definitionen u.ä.

8.7.5 Daten für self-lose Methoden?

• Methoden ohneself haben keinen Zugriff auf einenNamensraumeinesObjekts– Welches Objekts sollte das auch sein? Kann viele geben. . .

• Wir müssten also einen neuen Namensraum zur Verfügung stellen, der– . . . nicht an ein spezifisches Objekt gebunden ist– . . . aber mit der Klasse zu tun hat

Idee

• Die Klasse selbst bekommt ebenfalls einen Namensraum, in demDatenabgelegt werden können

• Und den haben wir ja schon! Das dict für Attribute bietet sich an!

8.7.6 Daten im Namensraum der Klasse – Erzeugen

• Erinnerung: Nach class folgt ein Block• Block: Liste von Anweisungen• Also darf man da z.B. Zuweisungen schreiben?

Ja!

1 class C:2 x = 13

4 c1 = C()

(PT link)

Visualisierung

Wie erwartet taucht im Attribute- dict der Klasse C ein Eintrag auf, der denNamen xmit demWert 1 verbindet (Abbildung 8.13).

8.7.7 Daten im Namensraum der Klasse vs. eines Objektes

1 class C:2 x = 13

4 def __init__(self, y):5 self.y = y6

Page 31: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.7. Statische Attribute und Methoden 31

Abbildung 8.13: Erweiterung des Attribute-dict um weitere Namen/Werte

7 c1 = C(17)8 c2 = C(18)

(PT link)

Beobachtung

• class führt Anweisungen im Block direkt aus!• Anders als def!

Visualisierung

Gehen wir dieses kleine Beispiel Schritt für Schritt durch.

1. Anlegen der KlasseMit Ausführen der ersten Zeile (Class C:) wird die Klasse selbst an-gelegt (Abbildung 8.14). D.h., es gibt im globalen Namensraum einenNamen C der auf die Beschreibung der Klasse referenziert.

Abbildung 8.14: Statische vs. dynamische Attribute: Anlegen der Klasse selbst

Page 32: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

32 Liste von Definitionen u.ä.

Um diese Beschreibung aufzubauen, werden die Anweisungen ausge-führt, die im Block von Class C stehen. Dies sind in diesem Beispielzwei Anweisungen:a) Die Zuweisung des Wertes 1 an den Namen xb) Die Zuweisung einer Funktion an den Namen __init__

Bei aller Ähnlichkeit zwischen def und class ist dies ein entschei-dender Unterschied! def als Anweisung führt keine Anweisungen desBlocks aus; es wird nur der Name der Funktion angelegt und mit demFunktionscode verbunden. class andererseits führt die Anweisungenaus, die im Block der Klasse enthalten sind!

2. Anlegen des Objektes c1Nach Ausführung des Konstruktors für das Objekt c1 referenziert derName c1 ein entsprechendes Objekt. Dieses Objekt besitzt in seinemeigenen Namensraum einen Eintrag für den Namen y, der auf den Wert17 verweist (Abbildung 8.15).

Abbildung 8.15: Statische vs. Objektattribute: Anlegen von c1

3. Anlegen des Objektes c2Abbildung 8.16 zeigt schließlich den Endzustand: Ein weiteres Objektder Klasse C existiert, mit einem eigenen Namensraum, bei dem derName y den Wert 18 referenziert.Der Namensraum der Klasse selbst hat nach wie vor unverändert denNamen x, der den Wert 1 referenziert.Anmerkung: die Zeichenkette y für das Attribut der beiden Objektemussnur einmal repräsentiert werden!

8.7.8 Daten im Namensraum der Klasse – Zugriff

Erster Versuch:

Page 33: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.7. Statische Attribute und Methoden 33

Abbildung 8.16: Statische vs. Objektattribute: Anlegen von c2

1 class C:2 x = 173 def f():4 print("f kennt Wert von x:", x)5

6 C.f()

Fehler

• Fehlermeldung:NameError: global name ’x’ is not defined• Plausibel!

– Nach bisherigen Regeln für Scopes von Funktionen (f ist eine Funk-tion!) ist x einen lokalen Namen von f* Und es gibt kein globales x

– Also funktioniert der Zugriff von x in Zeile 4 nicht• Aber wir wissen doch, wo x existiert! Im Namensraum von C!

8.7.9 Daten im Namensraum der Klasse – Optionen für Zugriff?

• Option 1: Wir ändern die Regeln, nach denen Scopes auf Namen hindurchsucht werden– Könnte gehen, wird aber problematisch mit Vererbung (siehe näch-ste Kapitel)

Page 34: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

34 Liste von Definitionen u.ä.

• Option 2: Wir ermöglichen, einen Namensraum explizit anzugeben, indem ein Name gesucht werden soll– Das geht und erweist sich auch später als praktisch– Zen: Explicit is better than implicit

8.7.10 Expliziter Namensraum für Zugriff

• Notation: Wir stellen den Namen des Namensraums dem zu benut-zenden Namen voran, mit . getrennt– Genauso wie bei Zugriff auf Funktion!

• Beispiel:

1 class C:2 x = 173 def f():4 print("f kennt Wert von x:", C.x)5 C.x += 16

7 C.f()8 C.f()

f kennt Wert von x: 17f kennt Wert von x: 18

8.7.11 Klassenname als Namensraum

• Notation für Zugriff auf Namensraum also ganz analog zu self!• Damit: Klassenname ist ebenso der Name eines Namensraums!

8.7.12 Terminologie

• Bei Objekten: dynamischeMethoden und Attribute• Bei Klassen: statischeMethoden und Attribute (static methods)

Anmerkung: Python kennt noch sogenannte class methods – lassen wir hierweg.

8.7.13 Beispiel: Anzahl der erzeugten Objekte zählen

• Idee: statisches Attribut als Zähler– In Klasse mit 0 initialisieren– In __init__ hochzählen– Mit statischer Methode ausgeben

• Siehe ebook für weitere Optionen

Page 35: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.7. Statische Attribute und Methoden 35

8.7.14 Beispiel: Anzahl der erzeugten Objekte zählen – Code

1 class Counted:2 zaehler = 03

4 def __init__(self):5 Counted.zaehler += 16

7 def printInstances():8 print("Erzeugt: {}".format(9 Counted.zaehler))10

11 c1 = Counted()12 c2 = Counted()13 Counted.printInstances()

Erzeugt: 2

8.7.15 Beispiel: MP3Player

• Für eine Klasse MP3Player, was sind dynamische, was statische Attri-bute/Methoden?

• Attribute: farbe, preis, verkaufteExemplare, songs• Methoden: batterieLaden(), playSong(), lauter(), rueckruf(), choose-Song()

8.7.16 Zusammenfassung: Dynamisch vs. statisch Attribute

Dynamisches Attribute Statische AttributeErzeugen Durch Zuweisung in

Objekt-Methode (ins.__init__)

Durch Zuweisung inClass Block oder mitexplizitem Namens-raum

Existenz in jedem Objekt einmal pro KlasseDaten ansprechen self.attributname Klassenname.attributnameMethoden aufrufen obj.method() Class.method()

Class.method(obj)

8.8 Beobachtungen

Page 36: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

36 Liste von Definitionen u.ä.

8.8.1 Überrascht?

• Eigentlich sollte Sie das alles nicht überrascht haben• Namen/Werte-Paare werden in einem dict abgelegt

– egal ob Klasse oder Objekt– egal ob normaler"Wert oder eine Funktion

• Namensräume können explizit angegeben werden– Egal ob Namensraum der Klasse oder des Objekts– Man braucht nur einen Namen dafür: die Klasse, oder self

• Alles recht einheitlich; wie sollte es anders sein?

8.8.2 Principle of least astonishment

• Neue Eigenschaften sollten nicht überraschend sein• Auch: Principle of least surprise• Eigentlich für Nutzerschnittstellen gedacht• Auch für Programmiersprachen/-paradigmen sinnvoll!• Siehe auch: Occams Messer

8.8.3 Analogien zwischen Klassen und Objekten?

• Objekte:– Haben ein dict für Attribute– Gehören zu einer Klasse, um dort Methoden zu finden

• Klassen:– Haben ein dict für Attribute– . . . ?

8.8.4 Klasse als Objekt?

• Kann man eine Klasse als ein Objekt auffassen?• Was wäre denn dann die "Klasse der Klasse"?• Was wären die Methoden für diese "Klasse als Objekt"?

8.8.5 Klasse als Objekt!

Ja!

• Eine Klasse selbst ist auch nur ein Objekt der speziellen Klasse type• Damit: Jede Klasse ist ein Type

– Wie int, list, etc.

Page 37: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.8. Beobachtungen 37

8.8.6 Erinnerung: Typkonvertierung

• Damit wird auch die Syntax der Typkonvertierung verständlich (vgl.Kapitel 5)!

• Bei Typkonvertierung wird, ganz normal, der Konstruktur der Klasse desgewünschten Typs aufgerufen– Mit dem zu konvertierenden Objekt als Parameter– Ergebnis: Objekt des gewünschten Typsmit entsprechendem Inhalt(oder Fehler)

• Beispiel:– int("12") vs. int("12.34")

8.8.7 Python: Everything is an Object

• Tatsächlich ist Python konsequent auf Objekte hin orientiert• Alles ist ein Objekt: Listen, Dicts, Funktionen, Klassen, selbst einfacheLiterale wie Integers und Zeichenketten

• Das hat Vor- und Nachteile– Vorteil: Konsistente Sprache, least astonishment, keine Widersprü-che* Gegenbeispiel Java: Viele Ausnahmen und Sonderfälle

– Nachteil: Aufwändig zur Laufzeit

8.8.8 Wie verschwinden Objekte?

• Wir haben Objekte explizit erzeugt durch Aufruf des Klassennamens– Objekt samt seines Namensraums entsteht– Belegt Platz im Speicher

• Wie verschwindet ein Objekt wieder?– Hoffnung: Nicht, so lange es noch gebraucht werden könnte– Woher weiß man, dass ein Objekt noch gebraucht wird?

8.8.9 Zählen: Referenzen auf Objekte

• Ein Objekt könnte noch gebraucht werden, so lange man es noch benut-zen kann

• Um es zu benutzen, muss man darauf zeigen können – es muss einenNamen geben, der das Objekt referenziert

• Wenn es keinen referenzierenden Namen mehr gibt, ist das Objekt ver-loren

• Dann kann man es vernichten

Also: Referenzen zählen

Page 38: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

38 Liste von Definitionen u.ä.

8.8.10 Referenzen zählen

Referenzen erzeugen

• Referenz auf Objekt entsteht im Moment der Konstruktion– Oft: einem Namen zugewiesen c = C()

• Referenz kann kopiert werden– Zuweisung an anderen Namen: c1 = c– Aufruf als Funktionsparameter: f(c)

Referenzen verlieren

• Referenzen gehen verloren, wenn Namensraum des referenzierendenNamens verschwindet!– Z.B. Funktion kehrt zurück– Z.B. ein anderes Objekt mit Referenz verschwindet

8.8.11 Referenzen zählen – Beispiel

Wieviele Referenzen existieren auf das Objekt der Klasse C am Ende des Pro-gramms?

1 import copy2

3 class C:4 Clist = []5 def __init__(self):6 C.Clist.append(self)7

8 def f(obj):9 newobj = copy.copy(obj)10 objlink = obj11 return objlink12

13 c = C()14 c = f(c)

8.8.12 Garbage Collection

• Wenn ein Objekt nicht mehr referenziert wird, dann vernichten– Das Objekt ist dann Müll (Garbage): Garbage Collection

• Automatischer Prozess!– Einer der großen Vorteile moderner Programmiersprachen bzw.Laufzeitsysteme

Page 39: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 39

– Vermeidet erhebliche Fehlerquellen• Man kann auch Objekte explizit löschen (mit del), aber selten notwen-dig

8.9 Beispiele

8.9.1 Vordefinierte Klasse: string

• Der Typ string für Zeichenketten ist als eine Klasse definiert• Er stellt reichhaltige Methoden zur Verfügung; Beispiele:

– count: Anzahl Vorkommen eines Teilstrings– find: Teilstring finden– format: Siehe folgende Folie– isnumeric: Ist das eine Zahl?– join: Siehe folgende Folie– endswith, startswith– splitlines: Zerteile den String in einzelne Zeilen; ergibt eineListe

• Siehe auch Python Dokumentation zu string

8.9.2 Methoden von string: format

• Ausgabe von Werten: Meist mit Text drum herum• Einfache Methode:

– In einer Zeichenkette {} für einzufügende Werte vorsehen– Auf diesen Zeichenkette Methode format anwenden, mit einemParameter pro {}-Paar

– Ersetzt {} mit übergebenen Werten• format kann Werte auch unterschiedlich formatieren

– Siehe Dokumentation zu Formatting-Syntax und Übung

Beispiel:

1 s = "Dies {} ein {} für {}!".format("ist", "Beispiel", "GP1")2 print(s)3

4 coord = (3.14, 2.71)5 s = "Der Punkt ist bei ({p[0]}, {p[1]})".format(p=coord)6 print(s)

Page 40: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

40 Liste von Definitionen u.ä.

Dies ist ein Beispiel für GP1!Der Punkt ist bei (3.14, 2.71)

8.9.3 Methoden von string: join

• Nimmt eine Liste von Strings als Parameter, verbindet die Liste mit demgegebenen String– Nur zwischen Elementen, nicht vor erstem oder nach letztem Ele-ment der Liste

• Sehr nützlich, um Listen kompakt auszugeben

1 l = ["17", "42", "abc"]2 print(l)3 print(" -- ".join(l))

['17', '42', 'abc']17 -- 42 -- abc

8.9.4 Stack

Ein Stack ist ein Last-In-First-Out (LiFo) Speicher:

• Beliebige viele Objekte können gespeichert werden• Man kann ein Objekt von oben auf den Stack legen: ein push• Man kann ein Objekt von oben wieder entnehmen: ein pop• Man kann nach der Anzahl der Objekte fragen• Man kann nicht irgendein Objekt von unten oder aus der Mitte entneh-men

8.9.5 Stack – UML

Abbildung 8.17 zeigt die UML-Darstellung einer Stack-Klasse.

Abbildung 8.17: Eine Stack-Klasse als UML-Diagramm

Page 41: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 41

8.9.6 Stack – Idee

• Die Daten legen wir in einer Liste ab– Erfüllt Anforderungen: beliebig groß, beliebige Objekte

• Die Stack-Methoden sind einfach auf Listen-Operationen abzubilden– Dank List-Slicing!

8.9.7 Stack – Code

1 class Stack:2 def __init__(self):3 self.daten=[]4

5 def push(self, d):6 self.daten.append(d)7

8 def pop(self):9 if len(self.daten) > 0:10 r, self.daten = self.daten[-1], self.daten[:-1]11 else:12 r = None13 return r14

15 def len(self):16 return len(self.daten)

8.9.8 Nochmal Ellipse

• Klasse Ellipse hat den Mittelpunkt explizit repräsentiert– Als x und y Koordinaten

• Aber ein Punkt ist doch auch ein Objekt?– Das in unterschiedlichen Kontexten vorkommt?– Ein Rechteck: zwei Eckpunkte– Ein Dreieck: drei Punkte

• Als eigene Klasse darstellen?– Ellipse nutzt diese Klasse?

8.9.9 Punkt als Klasse

1 class Punkt:2 def __init__(self, x, y):3 self.x = x4 self.y = y

Page 42: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

42 Liste von Definitionen u.ä.

5

6 def verschiebe(self, deltax, deltay):7 self.x += deltax8 self.y += deltay

8.9.10 Ellipse nutzt Punkt

1 class Punkt:2 ... # siehe oben3

4 class Ellipse:5 def __init__(self, mittelpunkt, a1, a2):6 self.mittelpunkt = mittelpunkt7 self.achse1 = a18 self.achse2 = a29

10 def verschiebe(self, deltax, deltay):11 self.mittelpunkt.verschiebe(deltax, deltay)

8.9.11 Muster: Delegation

• Klasse Ellipse delegiert Aufgaben an die Klasse Punkt• Delegation erzieltWiederverwendung von Funktionen

– Eine Klasse Rechteck ist mit Klasse Punkt einfacher zu schreibenals ohne

8.9.12 Ellipse mit Punkt: Erzeugen

1 class Punkt:2 def __init__(self, x, y):3 self.x = x4 self.y = y5

6 def verschiebe(self, deltax, deltay):7 self.x += deltax8 self.y += deltay9

10 class Ellipse:11 def __init__(self, mittelpunkt, a1, a2):12 self.mittelpunkt = mittelpunkt13 self.achse1 = a114 self.achse2 = a2

Page 43: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 43

15

16 def verschiebe(self, deltax, deltay):17 self.mittelpunkt.verschiebe(deltax, deltay)18

19 p = Punkt(1,2)20 e1 = Ellipse(p, 3, 4)21 e2 = Ellipse(Punkt(-2,3), 0.5, 7)

(PT link)

Visualisierung

Abbildung 8.18 illustriert (leider etwas unübersichtlich) bzw. Abbildung 8.19(kompakt, aber weniger präzise), wie sich die Delegation der Repräsentati-on des Mittelpunktes an eine Punkt-Klasse auswirkt. Es gibt natürlich zweiEllipsen-Objekte, referenziert durch e1 und e2. Zusätzlich gibt es zwei Punkt-Objekte. Das erste wird ebenfalls durch den Namen p (im globalen Scope)referenziert. Das zweite hat keinen eigenen globalen Namen; es wird aberdurch das Attribut mittelpunkt des durch e2 referenzierten Objektes refe-renziert.

Page 44: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

44 Liste von Definitionen u.ä.

Abbildung 8.18: Ellipse delegiert an Punkt

Page 45: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 45

Abbildung 8.19: Ellipse delegiert an Punkt, kompakte Darstellung

Beachten Sie, dass es zwei Methoden verschiebe gibt, die aber jeweils inunterschiedlichen Namensräumen referenziert werden und damit nicht miteinander in Konflikt stehen können.

8.9.13 Punkt: Abstand bestimmen

Abstand zwischen zwei Punkten bestimmen

• Option 1: Statische Methode der Klasse, bekommt zwei Parameter• Option 2: Normale Methode, hat self und ein anderes Objekt als Para-meter

Beispiel: Definition ähnlich; Benutzung unterschiedlich!

1 class Punkt:2 def __init__(self, x, y):3 self.x = x4 self.y = y5

6 def abstand(self, other):7 return (8 (self.x - other.x)**2 +9 (self.y - other.y)**210 )**0.511

Page 46: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

46 Liste von Definitionen u.ä.

12 def abstand2(o1, o2):13 return (14 (o1.x - o2.x)**2 +15 (o1.y - o2.y)**216 )**0.5

8.9.14 Telefonbuch

• Telefonbuch besteht aus Einträgen– Operationen: Hinzufügen, löschen, ändern, suchen

• Eintrag:– Name und Telefonnummer

8.9.15 Telefonbuch – UML

Abbildung 8.20 zeigt die UML-Darstellung einer Telefonbuch-Klasse.

Abbildung 8.20: Eine Telefonbuch-Klasse als UML-Diagramm

8.9.16 Telefonbuch – Code

1 class Telefonbuch:2 def __init__(self):3 eintraege = []4

5 def enter(self, name, phone):6 self.eintraege.append({'name': name,7 'phone': phone})8

9 def lookup(self, name=None, phone=None):10 if name:11 key, val = 'name', name12 elif phone:13 key, val = 'phone', phone14 else:

Page 47: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 47

15 return None16

17 for e in self.eintraege:18 if e[key] == val:19 return e20

21 return None

8.9.17 Lineare Liste durchsuchen?

• Telefonbuch sucht linear die Liste der Einträge ab– Alternativlos, da nicht sortiert

• Schneller? Einträge sortieren– Selection sort bei enter?– Möglich, aber mit linearer Liste nicht ideal

• Bessere Datenstruktur nötig!

8.9.18 Binärer Suchbaum

• Datenstruktur in Form eines Baums• Ein Knoten eines Baums enthält

– Ein eigentliches Datum (z.B. einen Telefonbucheintrag)– Einen Baum, in dem alle kleineren Einträge abgelegt werden – linkerTeilbaum

– Einen Baum, in dem alle größeren Einträge abgelegt werden – rech-ter Teilbaum

• Also: eine rekursive Datenstruktur• Darstellung hier folgt in etwa Interactive Python Beispiel

8.9.19 Binärer Suchbaum – Illustration

Vereinfachung: Hier nur Zahlen als Einträge, keine Telefonbucheinträge Ab-bildung 8.21 illustriert einen solchen Suchbaum.

8.9.20 Binärer Suchbaum – Operationen

Wesentlich:

• Einfügen• Suchen• Löschen• In Reihenfolge durchlaufen

8.9.21 Knoten eines Baums?

Was müssen wir über den Knoten eines Baumes wissen?

Page 48: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

48 Liste von Definitionen u.ä.

Abbildung 8.21: Ein binärer Suchbaum

• Den Suchschlüssel– Um größer, kleiner, gleich zu entscheiden

• Den eigentlichen Wert• Den linken und rechten Teilbaum (falls existent)

8.9.22 Binärer Suchbaum – Klassen

• Es bieten sich also hier zwei Klassen an:– Eine Klasse für die Knoten– Eine Klasse für den Baum als ganzes, der diese Knoten enthält

8.9.23 Binärer Suchbaum – UML

Abbildung 8.22 zeigt die UML-Darstellung von Suchbaum und Knoten-Klasse.

8.9.24 Klasse TreeNode

Eine insgesamt recht einfache Klasse:

1 class TreeNode:2 def __init__(self, key, val):3 self.key = key4 self.value = val5 self.leftChild = None6 self.rightChild = None7

8 def isLeaf(self):

Page 49: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 49

Abbildung 8.22: Suchbaum und Knoten als UML-Diagramm

9 return ((self.leftChild is None) and10 (self.rightChild is None))

8.9.25 Binärbaum – Grundgerüst

Der Konstruktor des Binärbaums ist auch einfach:

1 class BinaryTree:2 def __init__(self):3 self.root = None4 self.size = 05

6 def add(self, key, value):7 """Füge einen Eintrag unter key an die richtige Stelle ein"""8 ???9

10 def search(self, key):11 """Suche nach key; gib None falls nicht gefunden,12 sonst den TreeNode"""13 ???14

15 def remove(self, key):16 """Entferne Eintrag unter key falls vorhanden;17 erhalte Baumstruktur!"""18 ???19

Page 50: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

50 Liste von Definitionen u.ä.

20 def iterate(self):21 """Laufe den Baum in aufsteigender Reihenfolge22 der Knoten ab."""23 ???

8.9.26 Suchen

• Angenommen, wir haben schon einen Baum• Wie suchen wir darin?• Rekursives Vorgehen:

– Beginne bei der Wurzel – Ist das der gesuchte Schlüssel?* Ja? Fertig* Nein?

· Gesuchter Schlüssel kleiner? Suche links weiter· Sonst rechts

8.9.27 Suchen – Code

1 class BinaryTree:2 def search(self, key):3 # Wir benutzen intern eine etwas andere Funktion:4 # fuehre den aktuell zu untersuchenden Knoten als5 # Parameter mit6 return self._search(key, self.root)7

8 def _search(self, key, currentNode):9 """Hilfsfunktion: currentNode ist Zustand der Suche"""10 # Sonderfall abfangen: nicht gefunden:11 if currentNode is None:12 return None13

14 if key == currentNode.key:15 return currentNode16 elif key < currentNode.key:17 # suche im linken Teil weiter:18 return self._search(key, currentNode.leftChild)19 else:20 return self._search(key, currentNode.rightChild)

8.9.28 Python Konvention: Unterstrich

• Die Methode _search ist eine ganz normale Methode

Page 51: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.9. Beispiele 51

• Der Nutzer der Klasse kann diese genauso gut aufrufen wie die Methodesearch; daran ist nicht falsch

• Aber Konvention: Vorangestellter Unterstrich _ signalisiert, dass dieseMethode eher zum internen Gebrauch der Klasse gedacht ist

• Siehe PEP8

8.9.29 Einfügen – Rekursives Vorgehen

• Erinnerung: Bei rekursiven Datenstrukturen bieten sich rekursive Algo-rithmen an

• Einfügen rekursiv?– Einfacher Fall: Der Baum ist leer – direkt erzeugen– Wenn nicht leer: Ist das entsprechende Kind vorhanden?

* Wenn nein: Einfügen als Kind, fertig* Wenn ja: Rekursiv ab Kind einfügen!

8.9.30 Einfügen – Spezialfall

1 class BinaryTree:2 #.... wie oben3

4 def add(self, key, value):5 if self.root is None:6 # Baum ist leer, wir erzeugen den ersten Eintrag7 self.root = TreeNode(key, val)8 else:9 # Versuche, den Eintrag unter dem Knoten self.root einzufuegen10 # das wird laenger; also eigene Methode11 self._add(key, val, self.root)12

13 self.size += 1

8.9.31 Einfügen – Illustration

Abbildung 8.21 illustriert das Einfügen der Zahl 39 (in blau) und die dabeibesuchten Knoten (in grün).

8.9.32 Einfügen – allgemeiner Fall

1 class BinaryTree:2 def _add(self, key, value, currentNode):3 if key < currentNode.key:4 # fuege im linken Teil ein

Page 52: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

52 Liste von Definitionen u.ä.

Abbildung 8.23: Einfügen in einen binärer Suchbaum

5 if currentNode.leftChild is None:6 # hier muss der neue Knoten hin!7 currentNode.leftChild = TreeNode(key, value)8 else:9 # es gibt schon Kinder, suche dort weiter:10 self._add(key, value, currentNode.leftChild)11 elif key > currentNode.key:12 # der Fall is ganz symmetrisch13 if currentNode.rightChild is None:14 currentNode.rightChild = TreeNode(key, value)15 else:16 self._add(key, value, currentNode.rightChild)17 else:18 # wenn key schon existiert: aktualisiere Wert19 currentNode.value = value

8.9.33 Löschen – rekursiv

• Auch Löschen eines Eintrags geht rekursiv vor• Spezialfälle suchen

– Der einzige Knoten des Baums wird gelöscht– Ein Blatt wird gelöscht– Ein Knoten mit einem oder zwei Kindern wird gelöscht

• Allgemeinen Fall zusammensetzen

8.9.34 Löschen – Spezialfall

Wann ist Löschen eines Knoten einfach?

Page 53: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

8.10. Zusammenfassung 53

• Wenn keine Kinder!• Wurzel braucht allerdings Sonderbehandlung, wenn keine Kinder

1 class BinaryTree:2 def remove(self, key):3 if self.root.key == key and self.size == 1:4 # wir entfernen den letzten Knoten:5 self.root = None6 else:7 self._remove(key, self.rootNode)8

9 self.size -= 110

11 def _remove(self, key, currentNode):12 if key == currentNode.key:13 # zu loeschender Knoten gefunden -- hat er Kinder?

8.9.35 Hotel – Entwurfsdiskussion

Wie würde eine Klasse für eine Hotelverwaltung aussehen?

• Welche weiteren Klassen würden Sie für Delegation nutzen?• Welche Variabeln, Methoden brauchen Sie

8.10 Zusammenfassung

8.10.1 Zusammenfassung

• Klassen– sind ein Bauplan für Objekte– beschreiben Daten und Methoden für diese Daten an einer Stelle

• Objekte repräsentieren Dinge aus dem Kontext der Anschauung– Oft sehr anschaulich: Student, Punkt, Ellipse, Hotel, Hotelzimmer,Buchung

– Manchmal abstrakt: Binärer Suchbaum• Objekte entstehen durch Konstruktion (meist mit Initialisierung)

Page 54: Kapitel 8: Klassen und Objekte - groups.uni-paderborn.degroups.uni-paderborn.de/fg-karl/lehre/ws1819/gp1/vorlesung/ch8-classes/... · Kapitel 8: Klassen und Objekte Grundlagen der

54 Liste von Definitionen u.ä.

Abbildung 8.24: Begriffsüberlick der wesentlichen Begriff zu Klassen

8.10.2 Begriffsüberblick: Klassen, Attribute

8.10.3 Wie gehts es weiter?

• Klassen und Objekte in bisheriger Form sind schon recht nützlich– Kapseln Daten und Methoden zusammen an einer Stelle– Können direkt von anderem Code benutzt werden

• Aber was, wenn man nicht genau die richtige Klasse, aber eine ähnlichefindet?– Adaptieren?

8.10.4 Python-Keywords: Liste bis jetzt

• Bis jetzt:– True, False, and, or, def, return, None– in– if, else, pass, elif, while, for, break, continue, assert– global

• Neu:– class