14. Kapitel

Werbung
Kapitel 14:
Einführung in die Objekt-Orientierte
Programmierung
Einführung in die Informatik
Wintersemester 2007/08
Prof. Bernhard Jung
Übersicht
„
Grundzüge der Objektorientierten Programmierung (OOP)
am Beispiel von Python
‰
‰
‰
Einleitung
Verwendung vordefinierter Objekte in Python
Definition eigener Klassen in Python
„
„
„
„
Attribute und Methoden
Klassenattribute
Vererbung
Polymorphismus
Hauptlernziele
• Verständnis allgemeiner Prinzipen der OOP
• Fähigkeit, einfache objektorientierte Programme in Python schreiben können
Literatur
Michael Weigend. Objektorientierte Programmierung mit Python. 2. Aufl. Bonn (MITP) 2005.
Bernd Oestereich. Objektorientierte Softwareentwicklung. Oldenbourg. 1999
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
1
Was sind Objekte?
„
Reale Objekte
‰
„
z.B. Auto, Telefon, Mensch, Konto,
Versicherungspolice, …
Software-Objekte
‰
‰
Modellieren Ausschnitte der Realität
Sachgerechte Abstraktion
bzgl.
‰
‰
Eigenschaften / Attributen
Methoden / Verhalten / Operationen
/ Algorithmen
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
Objektorientierte Sichtweise: Welt als System von Objekten, die
untereinander Botschaften austauschen
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
2
Objekte besitzen Attribute
und beherrschen Methoden
Name: Sascha
Stadt: Berlin
Öffnungszeiten: Mo bis Fr 10:00-18:30
Attribute
(Daten)
Blumensträuße binden
Lieferauftrag entgegen nehmen
Boten schicken
Methoden
(Algorithmen)
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
Prof. B. Jung
Konzepte der OOP:
Klassen und Objekte
„
Klasse
‰
‰
‰
„
= Bauplan / Schema für Objekte
beschreibt prinzipiellen Aufbau (Eigenschaften/Attribute)
und Verhalten bei Erhalt von Nachrichten (verfügbare Methoden)
einer Menge von gleichartigen Objekten
Klassen verschmelzen logisch zusammengehörige Daten und Operationen zu
einer Einheit
Instanz (Objekt)
‰
= Konkretisierung / Inkarnation einer Klasse
„
‰
z.B. Mark und Sascha sind Instanzen von Blumenhändler
Alle Instanzen einer Klasse
„
„
Prof. B. Jung
beherrschen dieselben Methoden
haben dieselben Attribute (wenn auch mit verschiedenen Werten)
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
3
OOP in Python:
Arbeiten mit vordefinierten Klassen
„
„
Aufruf von Methoden eines Objekts mit Syntax: objekt.methode()
Methoden für Listen-Objekte
‰
‰
‰
‰
list.reverse() – Reihenfolge der Listenelemente wird umgekehrt
list.sort() – Sortierung der Listenelemente in aufsteigender Reihenfolge
list.extend(list2) – Liste wird um Elemente von list2 erweitert
…
>>>
>>>
>>>
[1,
>>>
>>>
[6,
>>>
>>>
[1,
Prof. B. Jung
l = [1,3,5,2]
l.extend([7,6])
print l
3, 5, 2, 7, 6]
l.reverse()
print l
7, 2, 5, 3, 1]
l.sort()
print l
2, 3, 5, 6, 7]
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
>>> help(list)
Help on class list in module __builtin__:
class list(object)
| list() -> new list
| list(sequence) -> new list initialized from sequence's items
|
| Methods defined here:
…
| append(...)
|
L.append(object) -- append object to end
|
| count(...)
|
L.count(value) -> integer -- return number of occurrences of value
|
| extend(...)
|
L.extend(iterable) -- extend list by appending elements from the iterable
|
| index(...)
|
L.index(value, [start, [stop]]) -> integer -- return first index of value
|
| insert(...)
|
L.insert(index, object) -- insert object before index
|
| pop(...)
|
L.pop([index]) -> item -- remove and return item at index (default last)
|
| remove(...)
|
L.remove(value) -- remove first occurrence of value
|
| reverse(...)
|
L.reverse() -- reverse *IN PLACE*
|
| sort(...)
|
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
|Prof. B. Jungcmp(x, y) -> -1, 0, Einführung
1
TU Bergakademie Freiberg
in die Informatik, WS 2007/08
4
OOP in Python:
Arbeiten mit vordefinierten Klassen
„
Beispiel: Erzeugen grafischer Benutzeroberflächen mit dem Modul "Tkinter"
„
Klasse Tk
‰
repräsentiert ein Fenster
Attribute, u.a.
‰
Methoden, u.a.
‰
„
„
„
‰
„
label
title(String)
mainloop()
Erzeugen von Tk-Objekten per Konstruktor: Tk()
Klasse Label
‰
repräsentiert einfaches Text-Element
Methoden, u.a.
‰
Erzeugen von Label-Objekten per Konstruktor: Label( Tk, …)
‰
„
Prof. B. Jung
pack()
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
OOP in Python:
Arbeiten mit vordefinierten Klassen
from Tkinter import *
fenster = Tk()
fenster.title("Hello World")
fenster.label = Label(fenster,
text="Hello Tkinter World")
fenster.label.pack()
fenster.mainloop()
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
5
OOP in Python: Definition eigener Klassen (1)
„
„
Definition von Klassen mit Schlüsselwort class
in besonderer Methode __init__ werden Attribute der Klasse initialisiert
‰
‰
‰
„
Konstruktor der Klasse, die bei Erzeugung von Instanzen aufgerufen wird
besondere Variable self referenziert das neue Objekt
Methode __init__ sollte immer als erstes Argument self haben
Instanzen werden durch Aufruf der Klasse erzeugt
‰
Argumente entsprechend Konstruktor, jedoch ohne erstes Argument
Beispiel: Objekte vom Typ "Kreis" beschrieben über Position (x,y) und Radius
class Circle1:
>>> c = Circle1()
Erzeugen einer Instanz
>>> print c
def __init__(self):
<__main__.Circle1 instance at 0x00B45850>
self.x = 0.0
>>> print c.x
self.y = 0.0
0.0
self.r = 1.0
>>> c.x = 2.0
>>> print c.x
2.0
>>> c.x, c.y = 1.5, 2.5
>>> print c.x, c.y
1.5 2.5
Prof. B. Jung
TU Bergakademie Freiberg
Einführung in die Informatik, WS 2007/08
>>>
OOP in Python: Definition eigener Klassen (2)
„
Konstruktor mit mehreren Argumenten
‰
‰
„
Bem: das Überladen von Methoden (z.B.: __init__ ) in derselben Klassendefinition - d.h.
gleicher Methodenname, aber unterschiedliche Argumente – ist in Python i.Ggs. zu anderen
OOP-Sprachen nicht möglich
stattdessen: Methoden mit Default-Argumenten
Definitionen der Methoden getPos(), setPos()
‰
‰
in Definition mit Argument self
bei Aufruf der Methode ohne Argument self
class Circle2:
def __init__(self,x=0.0,y=0.0,r=1.0):
self.x = x
self.y = y
self.r = r
def setPos(self, x, y):
self.x, self.y = x, y
>>> c = Circle2(2.0, 1.0, 1)
>>> c.getPos()
(2.0, 1.0)
>>> c.setPos(-1.0, 3)
>>> c.getPos()
(-1.0, 3)
>>> c.r
1
def getPos(self):
(self.x, self.y)
Einführung in die Informatik, WS 2007/08
Prof.return
B. Jung
TU Bergakademie Freiberg
6
Konzepte der OOP:
Geheimnisprinzip (Information Hiding)
„
Geheimnisprinzip (Information Hiding)
‰
‰
Auf die Attribute eines Objekts kann nicht direkt zugegriffen werden, stattdessen
erfolgt der Zugriff ausschließlich über Zugriffsoperatoren.
Es werden also die Implementierungen der Operationen und die Datenstrukturen
selbst versteckt.
„
Vorteil: Implementierungsdetails können beliebig geändert werden, ohne
Auswirkung auf den Rest des Programms zu haben
„
Bem: das Geheimnisprinzip wird in Python (wie auch in anderen OOPSprachen) nicht erzwungen. Es werden aber Möglichkeiten bereit gestellt,
Attribute nach außen zu verstecken
Æ Sichtbarkeit von Attributen (und Methoden)
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
OOP in Python: Sichtbarkeit von Attributen
„
Zugriff auf Attribute kann eingeschränkt werden
„
Öffentliche Attribute:
‰
‰
lesender und schreibender Zugriff auch außerhalb der Klassendefinition
z.B. Klasse Circle2
>>> c = Circle2(2.0, 10.0, 3.5)
>>> print c.x, c.y, c.r
2.0 10.0 3.5
„
Private Attribute
‰
‰
in Python Unterscheidung zwischen stark und schwach privaten Attributen
stark private Attribute
„
„
‰
Zugriff von außen überhaupt nicht möglich
syntaktisch: Attributname beginnt mit zwei Unterstrichen, z.B. __x
schwach private Attribute
„
„
Prof. B. Jung
Zugriff von außerhalb des Moduls (Phython-Skripts) eingeschränkt
syntaktisch: Attributname beginnt mit einem Unterstrich, z.B. _x
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
7
OOP in Python: Sichtbarkeit von Attributen
Beispiel
„
Klasse Circle3 mit (stark) privaten Attributen
‰
Zugriff auf Objekt-Attribute nur über getter- und setter-Methoden
class Circle3:
def __init__(self, x, y, r):
self.__x = x
self.__y = y
self.__r = r
def setX(self, x ):
self.__x = x
def getX(self):
return self.__x
def setRadius(self, r):
self.__r = r
def getRadius(self):
return self.__r
Prof. B. Jung
>>> c = Circle3(2.0, 10.0, 3.5)
>>> print c.__x
Traceback (most recent call last):
File "<pyshell#40>", line 1, in toplevelprint c.__x
AttributeError: Circle3 instance
has no attribute '__x'
>>> print c.getX()
2.0
>>>
TU Bergakademie Freiberg
Einführung in die Informatik, WS 2007/08
OOP in Python: Klassenattribute
„
Beispiel: Es soll ein Zähler __numCircles für die Anzahl der Instanzen einer Klasse
Circle4 erstellt werden
‰
‰
keine Eigenschaft einzelner Instanzen
gehört logisch zur Klasse Circle4
Initialisierung außerhalb von __init__
Æ Klassenattribut
class Circle4:
__numCircles = 0 # Klassenattribut
def __init__(self, x, y, r):
Zugriff mit Klassenname.Attributname
self.__x = x
self.__y = y
self.__r = r
Circle4.__numCircles = Circle4.__numCircles + 1
print "total number of circles = ", Circle4.__numCircles
Prof. B. Jung
>>> c1 = Circle4(1.0, 1.0,
total number of circles =
>>> c2 = Circle4(0.0, 0.0,
total number of circles =
>>> c3 = Circle4(3.0, 3.0,
total number of circles =
Einführung in die Informatik, WS 2007/08
>>>
1)
1
2)
2
3)
3
TU Bergakademie Freiberg
8
Konzepte der OOP - Vererbung
„
Oberklassen und Unterklassen in der Biologie
Quelle: de.wikipedia.org
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
Konzepte der OOP - Vererbung
„
Vererbung der Attribute (und Methoden) der Oberklasse an Unterklasse
‰
‰
‰
‰
d.h. alle geometrischen Figuren haben Position x, y
Kreis hat neben Position zusätzlich Radius
Rechteck hat neben Position zusätzlich Seitenlängen a, b
…
Geometrische Figur
Attribute: x, y
Kreis
Rechteck
Dreieck
Attribute: radius
Attribute: a, b
Attribute: a, b, c
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
9
OOP in Python - Vererbung
„
Definition von Oberklassen
class Klassenname(Oberklasse1, Oberklasse2 , …):
…
class GeomFig:
def __init__(self, x, y):
self.x = x
self.y = y
Circle hat Oberklasse GeomFig
class Circle(GeomFig):
def __init__(self, x, y, r):
GeomFig.__init__(self, x, y)
self.r = r
Prof. B. Jung
>>> c = Circle(1, 2, 4)
>>> print c.x, c.y, c.r
1 2 4
>>>
Aufruf des Konstruktors der Oberklasse
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
OOP in Python – Vererbung
Feinheiten
„
I.a. Vererbung von Attributen und Methoden an Unterklasse
‰
„
Unterklassen können Methoden der Oberklasse überschreiben
‰
‰
„
Unterklasse definiert namensgleiche Methode wie Oberklasse ("method overriding")
oft sinnvoll
Æ Polymorphismus …
Unterklassen können Attribute der Oberklasse überschreiben
‰
‰
„
stark private Attribute werden nicht vererbt
Unterklasse definiert namensgleiches Attribut wie Oberklasse ("shadowing")
meistens nicht sinnvoll
In Python ist auch Mehrfachvererbung möglich (d.h. mehr als eine Oberklasse)
‰
Mehrfachvererbung ist z.T. problematisch
(z.B. in Java daher nicht möglich)
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
10
Konzepte der OOP – Mehrfachvererbung
Nixon-Raute (Nixon diamond)
…
Quäker
def istPazifist():
return True
Republikaner
def istPazifist():
return False
Spezialisierung-von
Spezialisierung-von
Nixon
Problem: welche Methoden-Definition soll bei Objekten vom Typ Nixon gelten?
Æ in Python würde Methode der in der Klassendefinition zuerst genannten
Oberklasse angewendet
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
Konzepte der OOP - Polymorphismus
„
Polymorphismus ("Vielgestaltigkeit") :
‰
in verschiedenen Klassen können Methoden gleichen Namens definiert
werden
„
‰
auch: gleichnamige Methoden in Ober- und Unterklasse
(method overriding)
„
‰
„
in Python ist dies nicht möglich, aber vielen anderen OOP-Sprachen
auch in Python wichtiges Programmiermittel
damit verhalten sich die Instanzen der verschiedenen Klassen sehr
unterschiedlich bei Erhalt derselben Botschaft (d.h. Aufruf jeweils
unterschiedlicher Funktionen)
Beispiel
‰
Definition einer Methode drucke() in Oberklasse und in Unterklasse
…
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
11
OOP in Python – Polymorphismus / Method
Overriding
class GeomFig:
# Oberklasse
def __init__(self, x, y):
self._x = x
self._y = y
def drucke(self):
return "x=" + str(self._x) + " y=" + str(self._y)
class Circle(GeomFig):
# Unterklasse
def __init__(self, x, y, r):
GeomFig.__init__(self, x, y)
überschreibende Methode
self._r = r
def drucke(self):
return "x="+str(self._x) +" y="+ str(self._y) + " r="+str(self._r)
Prof. B. Jung
>>> g = GeomFig(0,0)
>>> g.drucke()
'x=0 y=0'
>>> c = Circle(1.0, 1.0, 2)
>>> c.drucke()
'x=1.0 y=1.0 r=2'
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
OOP in Python – Polymorphismus
die Methode __str__
„
besondere Methode __str__
‰
‰
‰
liefert eine String-Repräsentation eines Objekts zurück
wird von print und str() verwendet
(vordefiniert in impliziter Oberklasse object aller Python-Objekte)
class Circle(GeomFig):
def __init__(self, x=0.0, y=0.0, r=0.0):
GeomFig.__init__(self, x, y)
besondere Methode __str__
self._r = r
def __str__(self):
return "x="+str(self._x) + " y="+str(self._y) + " r="+str(self._r)
>>> o = object()
>>> o.__str__()
'<object object at 0x0099C438>'
>>> print o # benutzt __str__
<object object at 0x0099C438>
Prof. B. Jung
>>> c = Circle(5.0, 8.0, 1.0)
>>> c.__str__()
'x=5.0 y=8.0 r=1.0'
>>> print c
# benutzt __str__
x=5.0 y=8.0 r=1.0
>>> str(c)
Einführung in die Informatik,
WS 2007/08
'x=5.0
y=8.0 r=1.0' TU Bergakademie Freiberg
12
Sonstiges
„
Python-Klassen können auch ohne Methoden und ohne
Sichtbarkeitsmodifikatoren der Attribute (d.h. alle Attribute
öffentlich) definiert werden
‰
‰
d.h. Definition von Klassen ohne OOP-Prinzipien wie Geheimnisprinzip
Entsprechung in etwa zu 'Strukturen' in C oder 'Records' in Pascal
class Mitarbeiter:
def __init__(self, persnr, name, alter):
self.personalnr = persnr
self.name = name
self.alter = alter
>>> james = Mitarbeiter("007", "Bond", 35)
>>> print james.personalnr
007
>>> print james.name
Bond
>>> print james.alter
35
TU Bergakademie Freiberg
Einführung in die Informatik, WS 2007/08
Prof. B. Jung
Sonstiges
„
Python-Klassen können auch ganz ohne Methoden und Attribute
definiert werden
‰
‰
Æ "leere Klasse"
Hinzufügen von Attributen für Instanzen ist möglich
„
„
„
dies gilt für auch für Instanzen beliebiger Klassen
Dadurch auch Fehleranfälligkeit, z.B. Schreibfehler in Attributnamen
Verringerte Fehleranfälligkeit durch strikte Einhaltung des Geheimnisprinzips, d.h. kein
direkter Zugriff von außen auf Attribute, sondern nur auf Klassen
class Employee:
pass
leere Anweisung ("tue nichts!")
>>> john = Employee() # Erzeuge einen leeren Mitarbeiter-Satz.
# Fuelle die Felder des Satzes.
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
13
Zusammenfassung: Definition eigener Klassen in
Python
„
Klassendefinition: Klassenkopf + Klassenrumpf
„
Klassenkopf
‰
‰
‰
‰
„
Schlüsselwort class
Name der Klasse
evtl. Oberklassen in runden Klammern
Doppelpunkt
Klassenrumpf (eingerückt)
‰
Definition der Klassenattribute
Definition der __init__-Methode (Konstruktor)
‰
Definition weiterer Methoden
‰
„
darin Initialisierung der Objektattribute
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
Zusammenfassung: Konzepte der OOP
„
Objektorientierung =
Klassen und Objekte
+ Kommunikation mit Nachrichten
+ Vererbung
(Coad & Yourdon)
„
Objektorientierte Programmiersprachen
‰
‰
Java, C++, C#, Object Pascal (Delphi), Smalltalk, …
Python: strikt objektorientiert – alle Daten sind Objekte
Prof. B. Jung
Einführung in die Informatik, WS 2007/08
TU Bergakademie Freiberg
14
Herunterladen