10 Objektorientierte Programmierung, Teil 1



Ähnliche Dokumente
Grundlagen von Python

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Einführung in die Java- Programmierung

Primzahlen und RSA-Verschlüsselung

Informatik für Schüler, Foliensatz 21 Objektorientierte Programmierung

Java Kurs für Anfänger Einheit 5 Methoden

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Arbeiten mit UMLed und Delphi

Professionelle Seminare im Bereich MS-Office

Objektorientierte Programmierung

Dokumentation für das Spiel Pong

Informationsblatt Induktionsbeweis

7 Rechnen mit Polynomen

Anleitung über den Umgang mit Schildern

Software Engineering Klassendiagramme Assoziationen

Das Leitbild vom Verein WIR

Fotos verkleinern mit Paint

Objektorientierte Programmierung

Java: Vererbung. Teil 3: super()

Was meinen die Leute eigentlich mit: Grexit?

Zeichen bei Zahlen entschlüsseln

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Animationen erstellen

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Die Post hat eine Umfrage gemacht

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

Lineare Gleichungssysteme

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Informatik für Schüler, Foliensatz 23 Konstruktor, String-Methode und Heldenklassse

der Eingabe! Haben Sie das Ergebnis? Auf diesen schwarzen Punkt kommen wir noch zu sprechen.

Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung

Leichte-Sprache-Bilder

Monatstreff für Menschen ab 50 Temporäre Dateien / Browserverlauf löschen / Cookies

Wichtige Forderungen für ein Bundes-Teilhabe-Gesetz

Das RSA-Verschlüsselungsverfahren 1 Christian Vollmer

Sich einen eigenen Blog anzulegen, ist gar nicht so schwer. Es gibt verschiedene Anbieter. ist einer davon.

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:

Vorkurs C++ Programmierung

Objektorientierte Programmierung mit C++ Zusammenfassung der wichtigsten Topics rund um die objektorientierte Programmierung mit C++11

Schrittweise Anleitung zur Erstellung einer Angebotseite 1. In Ihrem Dashboard klicken Sie auf Neu anlegen, um eine neue Seite zu erstellen.

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Einführung in PHP. (mit Aufgaben)

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 22

ONLINE-AKADEMIE. "Diplomierter NLP Anwender für Schule und Unterricht" Ziele

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

Mathematik: Mag. Schmid Wolfgang Arbeitsblatt 3 1. Semester ARBEITSBLATT 3 RECHNEN MIT GANZEN ZAHLEN

Taylorentwicklung der k ten Dimension

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

icloud nicht neu, aber doch irgendwie anders

geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

Binärdarstellung von Fliesskommazahlen

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

a n auf Konvergenz. Berechnen der ersten paar Folgenglieder liefert:

Wollen Sie einen mühelosen Direkteinstieg zum Online Shop der ÖAG? Sie sind nur einen Klick davon entfernt!

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit

11 Objektorientierte Programmierung, Teil 2

Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER

Einführung in die Programmierung

Informatik 2 Labor 2 Programmieren in MATLAB Georg Richter

Herstellen von Symbolen mit Corel Draw ab Version 9

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

teischl.com Software Design & Services e.u. office@teischl.com

Bauteilattribute als Sachdaten anzeigen

Objektorientierte Programmierung OOP

Eine Anwendung mit InstantRails 1.7

Platinen mit dem HP CLJ 1600 direkt bedrucken ohne Tonertransferverfahren

Mind Mapping am PC. für Präsentationen, Vorträge, Selbstmanagement. von Isolde Kommer, Helmut Reinke. 1. Auflage. Hanser München 1999

Zwischenablage (Bilder, Texte,...)

Summenbildung in Bauteiltabellen mit If Then Abfrage

Einführung in die Programmierung

1. Standortbestimmung

Leit-Bild. Elbe-Werkstätten GmbH und. PIER Service & Consulting GmbH. Mit Menschen erfolgreich

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.

Wie halte ich Ordnung auf meiner Festplatte?

Woche 1: Was ist NLP? Die Geschichte des NLP.

Zimmertypen. Zimmertypen anlegen

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Technische Analyse der Zukunft

Alle gehören dazu. Vorwort

Benutzerverwaltung Business- & Company-Paket

EINFACHES HAUSHALT- KASSABUCH

4. AUSSAGENLOGIK: SYNTAX. Der Unterschied zwischen Objektsprache und Metasprache lässt sich folgendermaßen charakterisieren:

Lernwerkstatt 9 privat- Freischaltung

Einfügen von Bildern innerhalb eines Beitrages

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können.

Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten

Second Steps in eport 2.0 So ordern Sie Credits und Berichte

! " # $ " % & Nicki Wruck worldwidewruck

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Was ich als Bürgermeister für Lübbecke tun möchte

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: )

1. Adressen für den Serienversand (Briefe Katalogdruck Werbung/Anfrage ) auswählen. Die Auswahl kann gespeichert werden.

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Die Invaliden-Versicherung ändert sich

10.1 Auflösung, Drucken und Scannen

Objektorientierte Programmierung. Kapitel 12: Interfaces

Transkript:

10 Objektorientierte Programmierung, Teil 1 Wir lernen nun eine andere Technik (vor allem: eine andere Sichtweise) kennen, um unsere Programm zu organisieren, nämlich mittels Klassen und Objekten 184

Objekte, Attribute, Methoden Beginnen wir mit einer bekannten Konstruktion: für eine Liste a können wir bekanntlich mittels a.append( blub ) ein weiteres Element anfügen und wir wissen auch schon, dass append eine Methode und somit so was Ähnliches wie eine Funktion ist (Folie 75). Angenommen, wir hätten stattdessen eine Funktion. Dann hätte die außer dem anzufügenden Element noch die Liste als Parameter, etwa so: def append(liste, element): liste[len(liste):len(liste)] = [element] (Der slice sieht komisch aus ich wollte liste.append(element) aber vermeiden... ) Aufgerufen wird das dann z.b. so: a = [] append(a, blub ) 185

Prinzipiell brauchen wir also die Methode nicht, eine Funktion täte es auch. Die Methode ist aber netter, weil man so gleich sieht, dass sie etwas mit einer Liste zu tun hat. Wir nehmen nicht eine Funktion aus einem großen Topf und versorgen sie mit den nötigen Parametern, sondern wir bitten die Liste, sich zu verlängern. Diese Sichtweise ist ein wesentlicher Bestandteil der objektorientierten Programmierung und hilft uns, größere Programme vernünftig zu organisieren. Die Aktionen, die ein Objekt ausführen kann (seine Methoden), stellen wir uns als Bestandteile (Attribute) des Objektes vor. Außer Methoden wird ein Objekt normalerweise auch noch Daten speichern, auch die nennen wir Attribute des Objekts (in Python sind Methoden ein Spezialfall von Attributen). Ein Objekt stellen wir uns also ab jetzt als einen Container von Attributen (Methoden und Daten) vor. 186

Bevor wir neue Sorten von Objekten konstruieren, noch ein paar Beispiele für Methoden, die wir bisher verwendet haben, ohne sie zu bemerken. Zahlen haben eine Menge von Methoden, insbesondere für die arithmetischen Operationen (Details hierzu im Abschnitt 3.4.7 der Python Language Reference ). Beispiel Addieren ganzer Zahlen: da gibt es eine Methode add, die ein neues Objekt zurückliefert, deren Wert der Wert des Objektes plus der Wert des Parameters ist (sie wird aufgerufen, wenn ein Ausdruck wie a+5 ausgewertet wird): >>> a = 7 >>> print a. add (5) 12 Beachten: Der Name add beginnt und endet wie bei noch mehr speziellen Methoden, die wir heute kennen lernen werden mit je zwei Unterstrichen (damit man nicht aus Versehen eine Methode mit diesem Namen selber schreibt und dadurch Verwirrung stiftet). 187

Eine weit verbreitete Methode ist str ( Python Language Reference, 3.4.1), die eine Textdarstellung es Objktes als String zurückliefert. Zahlen können das: >>> a = 7. >>> a. str () + a. str () 7.07.0 aber auch z.b. Listen: >>> b = [1., 2., 3.] >>> b. str () [1.0, 2.0, 3.0] und sogar Funktionen geben sich Mühe: >>> import math >>> print math.sin. str () <built-in function sin> Diese Methode haben wir schon sehr oft benutzt: sie wird immer aufgerufen, wenn wir Objekte mit print drucken oder mit str in Strings umwandeln. Wenn wir neue Sorten von Objekten erzeugen, können wir denen eine geeignete Methode str mitgeben und schon lassen sie sich schön ausdrucken. 188

Neue Sorten von Objekten Neue Sorten von Objekten führt man folgendermaßen ein: Zunächst definiert man einen Bauplan für die neuen Objekte, die Klasse. Zu einer Klasse kann man dann Objekte erzeugen (instanziieren). Diese Objekte haben automatisch alle Attribute, die die Klassendefinition vorgibt (und können in Python auch beliebig weitere hinzufügen) Auf die Attribute eines Objekts können wir dann mittels Objekt.Attribut zugreifen. Problem dabei: Wie kann ein Objekt auf seine eigenen Attribute zugreifen? Lösung dazu: Alle Methoden eines Objektes bekommen beim Aufruf einen zusätzlichen Parameter übergeben, der an erster Stelle der Parameterliste steht und eine Referenz auf das Objekt selbst enthält. Dieser Parameter wird also als Formalparameter aufgeführt (Konvention ist, dass er self heißt), nicht aber als Aktualparameter. 189

Die Definition einer neuen Klasse ist in Python eine ausführbare Anweisung (d.h., sie wird erst bei Ausführung wirksam, analog zu einer Funktionsdefinition). Sie beginnt mit einer Zeile class Klassenname(object): (was es mit dem Teil (object) auf sich hat, lernen wir nächste Woche). Im darauf folgenden Block stehen bei uns vorerst Funktionsdefinitionen: Alle hier definierten Funktionen werden die Methoden der von dieser Klasse instanziierten Objekte. Später werden wir auch andere Anweisungen haben, die sinnvollerweise in einer Klassendefinition stehen können, vorerst brauchen wir die aber nicht. Zusätzlich zu den über die Klassendefinition erhaltenen Attributen kann ein Objekt in Python jederzeit beliebig weitere Attribute mittels einer Zuweisung Objekt.Attribut =... (bzw. self.attribut =... ) bekommen. 190

Der Konstruktor init Bevor wir ein Beispiel programmieren, sollten wir noch folgendes lernen: Wenn eine Klasse eine Methode init definiert (und das ist der Regelfall), wird diese automatisch aufgerufen, wenn ein Objekt instanziiert wird. Diese spezielle Methode heißt Konstruktor, sie hat als Parameter natürlich die Referenz auf das Objekt selber ( self ) und kann beliebig viele weitere Parameter haben (wo wir die Aktualparameter für die weiteren Parameter hinschreiben, sehen wir noch). Typischerweise finden in einem Konstruktor Zuweisungen der Art self.attribut =... die also neue Attribute des Objekts (nicht: der Klasse!) anlegen. Dadurch kann sichergestellt werden, dass alle Objekte der Klasse diese Attribute haben, die gleichnamigen Attribute dieser Art von verschiedenen Objekte sind aber verschiedene Variablen. 191

Eine Beispielklasse Ein einfaches Beispiel für eine Klassendefinition bekommen wir mit einer Klasse zum Speichern von Werten mit Einheiten hier seien es Zeitspannen. Wir definieren uns zunächst eine globale Variable mit einem Wörterbuch aller erlaubten Zeiteinheiten und ihren Entsprechungen in Sekunden: einheiten = { s :1., min :60., h :60.**2} Die Klassendefinition sieht vorerst nur vor: Einen Konstruktor, der als Parameter einen Wert (etwas, das wir in eine Fließkommazahl umwandeln können) und eine Einheit (ein String, der als Schlüssel in obigem Dictionary vorkommen muss). Beide Parameter sind optional mit Standardwerten 0 bzw s. Die Methode str, die den Wert umgewandelt in einen String verziert mit der Einheit zurückliefert. 192

einheiten = { s :1., min :60., h :60.**2} class Dauer(object): def init (self, wert=0., einheit= s ): self.wert = float(wert) if einheit in einheiten: self.einheit = einheit else: raise ValueError( Unzulaessige Einheit: \ + einheit) def str (self): return str(self.wert) + self.einheit Wenn ein neues Objekt erzeugt wird, verfügt es also über die Methoden init und str (aus der Klassendefinition) und über die Attribute wert und einheit (aus der Ausführung des Konstruktors vorausgesetzt, dass dabei kein Fehler aufgetreten ist). 193

Objekte instanziieren Objekte zu unserer Klasse bekommen wir durch einen Ausdruck, der wie ein Funktionsaufruf aussieht, aber statt Funktionsnamen den Klassennamen hat; in den Klammern stehen die Aktualparameter für den Konstruktor (bis auf self, das ja automatisch hinzugefügt wird), sofern vorhanden/erforderlich. Dadurch wird ein neues Objekt der Klasse erzeugt, der Konstruktor ausgeführt und wir bekommen eine Referenz auf das neue Objekt, die wir in der Regel irgendwo speichern werden. Hier erzeugen wir gleich eine Liste mit vier Objekten unserer Klasse (wegen der optionalen Parameter von init gibt s verschiedene Varianten der Parameterliste) und drucken sie aus (dabei wird ja jeweils das str ausgeführt): tlist = [Dauer(), Dauer(1), Dauer(5, h ), Dauer(einheit= min )] for t in tlist: print t 194

Weitere Beispiele für Methoden Damit niemand auf die Idee kommt, Methodennamen hätten immer Unterstriche außenrum (das ist nur bei den Methoden mit Spezialfunktion der Fall), schreiben wir noch schnell wenigstens eine normale Methode. Unsere Objekte sollen berechnen können, wie vielen Sekunden die gespeicherte Dauer entspricht. Dazu fügen wir in die Klassendefinition einfach noch folgende Definition ein: def sekunden(self): return self.wert*einheiten[self.einheit] Dann können wir (mit einer Liste tlist wie oben) z.b. schreiben for t in tlist: print t, (entspricht, t.sekunden(), s) 195

Zurück zu Methoden mit Spezialfunktion... Bei Auswertung eines Ausdrucks der Form x + y wird die Methode x. add (y) aufgerufen (vorausgesetzt, es gibt sie). Dadurch können wir leicht Zeiten addieren. Die Methode add (natürlich auch in die Klassendefinition einzufügen) muss sich dabei um die Einheiten kümmern hier erzeugen wir als Ergebnis ein neues Objekt der Klasse Dauer mit der Einheit von x, müssen also y in diese Einheit umrechnen: def add (self, other): e1 = einheiten[self.einheit] e2 = einheiten[other.einheit] return Dauer(self.wert + other.wert*e2/e1,\ self.einheit) Das y von oben entspricht hier also dem Parameter other. Ausprobieren: print Dauer(5, h ) + Dauer(30, min ) druckt 5.5h 196

Klassenattribute Unschön an unserem Beispiel ist noch, dass das Dictionary mit den Einheiten eine globale Variable ist das widerspricht dem Gedanken, alles, was die Objekte ausmacht, zusammenzupacken. Hier ließe es sich leicht als eine lokale Variable des Konstruktors realisieren, weil wir es ja hinterher nie mehr brauchen. Um die folgenden Erläuterungen zu motivieren, sollten wir daher annehmen, dass das Dictionary von anderen Methoden noch gebraucht würde und alle Objekte der Klasse auf dasselbe Dictionary zugreifen sollen. Attribute, die das können, nennt man Klassenattribute, sie werden durch eine Bindung (i.d.r: eine Zuweisung) innerhalb der Klassendefinition erzeugt. Zugreifen können wir auf die Klassenattribute: Über Objekte dieser Klasse wie bei gewöhnlichen Attributen: Objekt.Attribut Das ist aber oft irreführend, weil alle diese Zugriffe dieselbe Variable verwenden, egal welches Objekt wir verwenden. Oft besser: Klasse.Attribut ist für Klassenattribute auch erlaubt (und funktioniert auch dann, wenn es gar kein Objekt dieser Klasse gibt). 197

class Dauer(object): einheiten = { s :1., min :60., h :60.**2} def init (self, wert=0., einheit= s ): self.wert = float(wert) if einheit in Dauer.einheiten: self.einheit = einheit else: raise ValueError( Unzulaessige Einheit: \ + einheit) def str (self): return str(self.wert) + self.einheit def sekunden(self): return self.wert*dauer.einheiten[self.einheit] def add (self, other): e1 = Dauer.einheiten[self.einheit] e2 = Dauer.einheiten[other.einheit] return Dauer(self.wert + other.wert*e2/e1,\ self.einheit) 198

Um das Wesen von Klassenatrributen zu verdeutlichen, schreiben wir noch eine Methode, mit der wir eine neue Einheit hinzufügen können. Als Parameter bekommt sie einen Namen (z.b. d ) und eine Dauer (z.b. Dauer(24, h )): def neue_einheit(self, name, laenge): self.einheiten[name] = laenge.sekunden() Probieren wir es aus: t = Dauer(24, h ) t.neue_einheit( d, t) print Dauer.einheiten t1 = Dauer(1./24., d ) print t1, (entspricht %gs) % t1.sekunden() Das druckt folgendes: { h : 3600.0, s : 1.0, d : 86400.0, min : 60.0} 0.0416666666667d (entspricht 3600s) Man beachte, dass der Methodenaufruf von t das Dictionary der ganzen Klasse verändert hat. Dauer.einheiten[name] wäre natürlich auch gegangen. 199

Klassenmethoden Jetzt ist aber blöd, dass wir die Methode neue einheit über ein Objekt aufrufen müssen, obwohl sie mit dem speziellen Objekt gar nichts zu tun hat. Solche Methoden, die keine Objektattribute, sondern nur Klassenattribute verwenden, kann man als Klassenmethode definieren. Man stellt ihnen dazu ein @classmethod voran, der erste Parameter ist nun kein Bezug auf ein Objekt, sondern auf die Klasse (und heißt deshalb normalerweise cls und nicht self). In unserem Beispiel: @classmethod def neue_einheit(cls, name, laenge): cls.einheiten[name] = laenge.sekunden() Nun können wir die Methode über die Klasse aufrufen: t = Dauer(24, h ) Dauer.neue_einheit( d, t) t1 = Dauer(1./24., d ) print t1, (entspricht %gs) % t1.sekunden() 200

Selber machen! Vorschlag zum Selbermachen: eine Klasse für Polynome. Ein Polynomobjekt hat als Attribut eine Liste mit den Koeffizienten a i aus p(x) = n i=0 a i x i Der Konstruktor bekommt so eine Liste als Parameter und speichert eine Kopie davon ab (Kopie ist besser, schließlich sind Listen veränderbar... ). Dann schreiben wir die Methode str, um Polynome schön ausdrucken zu können (z.b. 3*x**2-2*x + 1) Eine Methode wert mit einer Zahl x als Parameter soll p(x) zurückliefern, eine parameterlose Methode grad den Grad des Polynoms (größter Exponent mit Koeffizient ungleich Null; der Grad des Nullpolynoms sei hier -1). 201

Wenn wir Methoden add und mul analog zu Folie 196 bereitstellen, können wir Polynome addieren und multiplizieren (vor allem beim Addieren muss man ein wenig aufpassen wegen der möglicherweise unterschiedlichen Längen der Koeffizientenvektoren, und beim Multiplizieren probt man das lieber erst mal mit Papier und Bleistift, bevor man es programmiert) 202