Kapitel 19: Klassen und Unterklassen - Pi1 - Universität Mannheim
Kapitel 19: Klassen und Unterklassen - Pi1 - Universität Mannheim
Kapitel 19: Klassen und Unterklassen - Pi1 - Universität Mannheim
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Kapitel</strong> <strong>19</strong>:<br />
<strong>Klassen</strong> <strong>und</strong> <strong>Unterklassen</strong><br />
Felix Freiling<br />
Lehrstuhl für Praktische Informatik 1<br />
<strong>Universität</strong> <strong>Mannheim</strong><br />
Vorlesung Praktische Informatik I<br />
im Herbstsemester 2009<br />
Folien nach einer Vorlage von<br />
H.-Peter Gumm, Philipps-<strong>Universität</strong> Marburg
Übersicht<br />
<strong>Unterklassen</strong><br />
Vererbung, super, over-riding<br />
Applets<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 2
Rückblick: Klasse Konto<br />
Modelliert ein Bankkonto<br />
Enthält Felder für<br />
Kontostand, Inhaber, Kontonummer<br />
Felder sind private<br />
Von außerhalb der Klasse nicht<br />
zugreifbar<br />
Methoden zum Lesen <strong>und</strong> Verändern<br />
der Felder<br />
getter/Observer<br />
setter/Mutator<br />
Konto<br />
Felder:<br />
static int naechsteKontonummer<br />
private int kontostand<br />
private String inhaber<br />
private int nummer<br />
Methoden:<br />
getter<br />
int getKontostand()<br />
int getInhaber()<br />
int getNummer()<br />
…<br />
setter<br />
void einzahlen(int)<br />
void überweisen(Konto, int)<br />
void abheben (int)<br />
...<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 3
Spezielle <strong>Klassen</strong><br />
Wir wollen spezielle Konten implementieren<br />
Girokonten<br />
Man kann überziehen, muss dann aber Zinsen zahlen<br />
Es gibt keine Habenzinsen<br />
Sparkonten<br />
man erhält Zinsen,<br />
man kann nicht überziehen<br />
man kann von Sparkonten nicht überweisen<br />
Wir könnten separat jeweils neue <strong>Klassen</strong> mit allen Feldern <strong>und</strong> Methoden schreiben<br />
class Sparkonto {<br />
...<br />
int nummer;<br />
String inhaber;<br />
static int sparZinssatz = 3;<br />
}<br />
int getInhaber(){<br />
return inhaber;<br />
}<br />
...<br />
class Girokonto {<br />
...<br />
int nummer;<br />
String inhaber;<br />
static int kreditZinssatz = 13;<br />
int limit=10000;<br />
...<br />
int getInhaber(){<br />
return inhaber;<br />
}<br />
...<br />
}<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 4
Modellierung als <strong>Unterklassen</strong><br />
Immer wenn man Funktionalität in anderen <strong>Klassen</strong><br />
wiederverwenden möchte, sollte man über <strong>Unterklassen</strong><br />
<strong>und</strong> Vererbung nachdenken<br />
Wiederverwendung der Basisfunktionalität der Klasse Konto<br />
Sparkonten <strong>und</strong> Girokonten sind spezielle Konten<br />
Jedes GiroKonto kann benutzt werden wie ein Konto<br />
Die Klasse GiroKonto ist eine Unterklasse der Klasse Konto<br />
Jedes SparKonto kann benutzt werden wie ein Konto<br />
Die Klasse SparKonto ist eine Unterklasse der Klasse Konto<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 5
Vererbung / Erweiterung<br />
<strong>Unterklassen</strong> <strong>und</strong> ihre Objekte haben zusätzliche Eigenschaften<br />
Sie „erben“ alle (nicht privaten) Felder <strong>und</strong> Methoden<br />
der Oberklasse<br />
Sowohl Sparkonten als auch Girokonten haben automatisch<br />
Die Felder nummer, kontostand, inhaber<br />
Die Methoden getKontostand, einzahlen, abheben<br />
Sie können zusätzliche Felder haben<br />
Sparkonten<br />
Was ist der sparZinssatz<br />
Wann wurde letztmals Zins gutgeschrieben<br />
Girokonten<br />
Was ist der Überziehungszins<br />
Was ist das Überziehungslimit<br />
Seit wann ist überzogen<br />
Sie können zusätzliche Methoden haben<br />
Sparkonten<br />
Zinsen gutschreiben<br />
Girokonten<br />
Gebühr abziehen<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 6
<strong>Unterklassen</strong> in Java<br />
Mit dem Schlüsselwort extends beerbt<br />
eine Klasse eine andere Klasse:<br />
class SparKonto extends Konto{<br />
...<br />
static int sparZinssatz = 3;<br />
int letzterZinsTag;<br />
int getSparZinsSatz(){<br />
return sparZinsSatz;<br />
}<br />
void zahleZinsen(){<br />
. . .<br />
class GiroKonto extends Konto{<br />
...<br />
static int kreditZinssatz = 13;<br />
int letzterRechnungsTag;<br />
int limit=10000;<br />
int getLimit(){<br />
return limit;<br />
}<br />
void berechneGebühr(){<br />
. . .<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 7
Zugriff auf Oberklasse<br />
private Felder sind privat<br />
auch aus der Unterklasse aus nicht<br />
zugreifbar<br />
getter <strong>und</strong> setter sollten genügen<br />
protected Felder sind<br />
zugreifbar aus der Unterklasse<br />
nicht zugreifbar aus anderen <strong>Klassen</strong><br />
ungeschützte Felder sind<br />
zugreifbar von allen <strong>Klassen</strong> des<br />
gleichen Pakets<br />
nicht zugreifbar aus <strong>Klassen</strong> anderer<br />
Pakete<br />
„package private“<br />
Konto<br />
Felder:<br />
static protected int zinssatz<br />
protected int kontostand<br />
String inhaber<br />
private int nummer<br />
Methoden:<br />
getter<br />
int getKontostand()<br />
int getInhaber()<br />
int getNummer()<br />
…<br />
setter<br />
void einzahlen(int)<br />
void überweisen(Konto, int)<br />
void abheben (int)<br />
...<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 8
Zugriffe aus der Unterklasse<br />
Konto<br />
Felder:<br />
protected int kontostand<br />
String inhaber<br />
private int nummer<br />
Methoden:<br />
getter<br />
int getKontostand()<br />
int getInhaber()<br />
int getNummer()<br />
…<br />
setter<br />
void einzahlen(int)<br />
void überweisen(Konto, int)<br />
void abheben (int)<br />
...<br />
class SparKonto extends Konto{<br />
void zahleZinsen(){<br />
einzahlen( kontoStand * sparZinsSatz); );<br />
} // o.k.<br />
void druckeAuszug(){<br />
System.out.println(inhaber); //o.k.<br />
System.out.println(nummer); //falsch<br />
System.out.println(kontoStand); //o.k.<br />
}<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 9
Die Unterklasse in BlueJ<br />
Diese Pfeile zeigen an, dass SparKonto<br />
<strong>und</strong> Girokonto <strong>Unterklassen</strong> von Konto sind.<br />
Jedes Objekt der Teilklasse<br />
- hat zusätzliche Methoden<br />
- erbt alle Methoden der Oberklasse:<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 10
Eine Klasse mit <strong>Unterklassen</strong><br />
Klasse Konto mit<br />
<strong>Unterklassen</strong><br />
GiroKonto <strong>und</strong><br />
SparKonto<br />
<strong>und</strong> eine Klasse, die die<br />
letzteren benutzt.<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 11
Overriding: über-definieren<br />
Methoden der Oberklasse können<br />
in der Unterklasse verändert werden:<br />
z.B. kann die Methode abheben in der Unterklasse<br />
Sparkonto neu definiert werden:<br />
class Sparkonto extends Konto{<br />
...<br />
void abheben(int betrag){<br />
if (getKontoStand() >= betrag)<br />
super.abheben(betrag);<br />
}<br />
. . .<br />
Die Methode abheben der Oberklasse, hier Konto.<br />
Nur falls ( if )<br />
(kontoStand ≥ betrag )<br />
ist führe die Aktion aus.<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 12
Klasse - Unterklasse<br />
Wann sollte man eine Klasse als Unterklasse<br />
einer bestehenden Klasse modellieren?<br />
Nur wenn es begrifflich Sinn macht<br />
Jeder Kreis ist eine Figur,<br />
jede Figur ist ein geometrisches Objekt,<br />
jedes Sparkonto ist ein Konto,<br />
jeder PKW ist ein Fahrzeug<br />
„... ist ein ...“<br />
≈<br />
„...kann benutzt werden wie...“<br />
Nur wenn jedes Objekt der neuen Klasse als spezielles Objekt der bereits<br />
bestehenden Klasse angesehen werden kann<br />
Quadrat ist ein spezielles Rechteck,<br />
ein Kreis ist eine spezielle Ellipse,<br />
ein Sparkonto ist ein spezielles Konto,<br />
eine ganze Zahl ist eine spezielle rationale Zahl<br />
Nur wenn die Methoden der Oberklasse auch in der Unterklasse<br />
Sinn machen.<br />
makeVisible() der Klasse Figur macht auch Sinn für jeden Kreis,<br />
länge(), breite() <strong>und</strong> fläche() der Klasse Rechteck machen auch Sinn für Quadrate,<br />
referenzPunkt() der Klasse GeometrischesObjekt macht auch Sinn für Kreise<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 13
super<br />
verweist von der Unter- in die Oberklasse<br />
class Sparkonto extends Konto{<br />
}<br />
// Wir übernehmen den<br />
// Konstruktor der Oberklasse<br />
SparKonto(String x){<br />
super(x);<br />
letzterZinsTag = 0;<br />
}<br />
...<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 14
Fallstricke<br />
In vielen Fällen haben Objekte der Unterklasse zusätzliche Felder<br />
Ein SparKonto ist ein Konto mit zusätzlichen Feldern, z.B. sparZins,<br />
letzterZinstag, ...<br />
Ein PKW ist ein Fahrzeug mit zusätzlichen Feldern, z.B.<br />
personenZahl, ...<br />
Eine MusikCD bzw. ein Film ist ein spezielles MedienKunstwerk, die<br />
neben autor, titel <strong>und</strong> herstellungsJahr noch titelListe <strong>und</strong><br />
musikGenre bzw. schauspielerListe <strong>und</strong> kameramann hat.<br />
Allein die Tatsache, dass Objekte der Klasse B mehr Felder haben,<br />
als Objekte der Klasse A macht B noch nicht zur Unterklasse von A<br />
Ein Quadrat hat eine länge, ein Rechteck hat länge <strong>und</strong> breite.<br />
Ein Rechteck ist aber kein spezielles Quadrat – ganz im Gegenteil !<br />
Eine RationaleZahl hat zähler <strong>und</strong> nenner, eine GanzeZahl nur<br />
zähler. RationaleZahlen sind aber nicht spezielle GanzeZahlen –<br />
im Gegenteil !<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 15
Eingebaute Java-<strong>Klassen</strong> erweitern<br />
<strong>Klassen</strong> erweitern, heißt <strong>Unterklassen</strong> bilden<br />
Unterklasse erbt alle Felder <strong>und</strong> Methoden der Oberklasse<br />
Sparkonto <strong>und</strong> Girokonto erben Funktionalität von Konto<br />
Java hat eine umfangreiche <strong>Klassen</strong>-Bibliothek<br />
Fast jede )* der <strong>Klassen</strong> kann man erweitern:<br />
Um ein Applet zu schreiben beerbt man die Klasse<br />
Applet. Sie stellt Methoden bereit,<br />
ein Applet im Browser darzustellen<br />
es zu starten bzw. zu stoppen, wenn das<br />
Browserfenster verändert wird<br />
Auf der Leinwand des Applets zu schreiben,<br />
zeichnen, Buttons <strong>und</strong> Menüs anzubringen<br />
Um User-Interfaces zu schreiben beerbt man die <strong>Klassen</strong><br />
Graphics, Event, Menu, Color, Window,<br />
Button, ... (siehe <strong>Kapitel</strong> 20)<br />
... die sich in dem in dem Paket java.awt befinden.<br />
)* alle <strong>Klassen</strong>, die nicht als final deklariert wurden<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 16
Die Klasse Applet<br />
WWW-Browser benutzen die Klasse Applet<br />
Der Browser erzeugt zunächst ein Applet<br />
new Applet( … )<br />
das Applet wird initialisiert durch die Methode<br />
init()<br />
<strong>und</strong> gestartet mit<br />
start()<br />
Wechselt der Browser zu einer anderen Webseite, so<br />
ruft er die Methode<br />
stop()<br />
Kommt er zurück, erfolgt wieder ein<br />
start()<br />
Jedesmal, wenn das Applet neu zu zeichnen ist<br />
beim Start<br />
wenn das Browserfenster Größe oder Position ändert,<br />
ruft der Browser die als public erklärte Methode<br />
paint()<br />
mit Signatur void paint(Graphics g) auf.<br />
Ein Applet programmieren heißt:<br />
Einige der genannten Methoden re-definieren.<br />
init()<br />
start()<br />
stop()<br />
destroy()<br />
paint()<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 17
Wir beerben die Klasse Applet<br />
Die Methoden (paint, init, start, stop, destroy) werden von außen – von<br />
dem Browser – aufgerufen.<br />
Klasse <strong>und</strong> ihre Methoden müssen daher public sein<br />
Wir beerben die Klasse<br />
java.applet.Applet<br />
Wir redefinieren<br />
paint()<br />
Wir benutzen die <strong>Klassen</strong><br />
java.awt.Graphics<br />
java.awt.Color<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 18
Ausführen in BlueJ<br />
Nach dem<br />
Kompilieren hat das<br />
Kontextmenü der<br />
Klasse „Äpfelchen“<br />
eine Auswahl:<br />
Run Applet<br />
wir wählen eine<br />
Dimension aus <strong>und</strong><br />
sehen das Ergebnis<br />
per appletviewer<br />
dargestellt<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite <strong>19</strong>
Applet in Webpage einbinden<br />
Ein Applet lässt sich<br />
leicht in eine<br />
Webseite einbinden<br />
HTML-Marke:<br />
<br />
Wichtigste<br />
Parameter: code,<br />
width, height<br />
Code-Datei hier:<br />
Äpfelchen.class<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 20
Nicht gerade spektakulär ...<br />
Die HTML-Datei - in verschiedenen Browsern<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 21
Übersicht<br />
<strong>Unterklassen</strong><br />
Vererbung, super, over-riding<br />
Applets<br />
Ausblick: <strong>Kapitel</strong> 20, Verwendung von Vererbung zur<br />
Programmierung einer grafischen Benutzerschnittstelle<br />
Mehr zu Objektorientierung in der<br />
Vorlesung “Wirtschaftsinformatik II”<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 22
Fallstudie zur<br />
Vererbung:<br />
Personendatenbank<br />
Anhang zu <strong>Kapitel</strong> <strong>19</strong> der Vorlesung<br />
“Praktische Informatik I”
Fallstudie: Datenbank<br />
Basiert auf dem BlueJ-<br />
Beispielprojekt people<br />
Modelliert eine Datenbank<br />
für eine Uni<br />
Datenbank enthält<br />
Studierende, Mitarbeiter<br />
<strong>und</strong> andere Personen<br />
Studierende <strong>und</strong> Mitarbeiter<br />
als <strong>Unterklassen</strong> von<br />
Person modelliert<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 24
Entwurf: Klasse Person<br />
Eine Person hat einen Namen <strong>und</strong> ein<br />
Geburtsjahr<br />
Objektfelder name <strong>und</strong> geburtsjahr, beide<br />
private<br />
Anonyme Personen sollen erlaubt sein<br />
Man kann beide Felder lesen <strong>und</strong><br />
setzen<br />
Man kann eine Person in eine<br />
Zeichenkette umwandeln<br />
Re-Definition der Methode toString()<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 25
Entwurf: Klasse Student<br />
Ein Student kann auch wie eine Person<br />
benutzt werden<br />
Unterklasse von Person<br />
Hat zusätzlich eine Matrikelnummer<br />
Zusätzliches privates Objektfeld String<br />
matrikelnummer<br />
Hat zusätzlich Methoden, die die<br />
Matrikelnummer lesen<br />
Soll auch in eine Zeichenkette<br />
umgewandelt werden können<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 26
Entwurf: Klasse Mitarbeiter<br />
Ähnlich wie Student, als<br />
Erweiterung der Klasse<br />
Person<br />
Hat zusätzlich ein Büro<br />
privates Feld String<br />
bueroBezeichnung<br />
Hat Methoden, um dieses Feld<br />
zu lesen <strong>und</strong> zu setzen<br />
Soll auch in eine Zeichenkette<br />
umgewandelt werden können<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 27
Implementierung: Person<br />
Standard-Konstruktor:<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 28
Implementierung: Person<br />
Speziellere Konstruktoren<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 29
Implementierung: Student<br />
Standard-Konstruktor:<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 30
Implementierung: Student<br />
Erweiterter Konstruktor:<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 31
In Zeichenkette umwandeln<br />
In der Klasse Person<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 32
In Zeichenkette umwandeln<br />
In der Klasse Student:<br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 33
Vorteile abgeleiteter <strong>Klassen</strong><br />
Man kann die Klasse Person verwenden, ohne<br />
zu wissen, wie sie implementiert ist<br />
Erspart einem die Definition <strong>und</strong> Behandlung der<br />
Felder, die eine Person hat<br />
Ähnliches kann man auch mit den Standard-<br />
Java-<strong>Klassen</strong> machen<br />
Siehe Beispiel Applet in <strong>Kapitel</strong> <strong>19</strong><br />
Praktische Informatik I, HWS 2009, <strong>Kapitel</strong> <strong>19</strong> Seite 34