06.10.2013 Aufrufe

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

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!