Title: Vorlesung EINI / Kapitel 8 (Teil 4)
1Wintersemester 2006/07
EinfĂĽhrung in die Informatik fĂĽr Naturwissenschaft
ler und Ingenieure (alias EinfĂĽhrung in die
Programmierung) (Vorlesung)
Prof. Dr. GĂĽnter Rudolph Fachbereich
Informatik Lehrstuhl fĂĽr Algorithm Engineering
2Kapitel 11 Vererbung
- Ziele von Klassen
- Schon besprochen
- Kapselung von Attributen (wie struct in
Programmiersprache C) - Kapselung von klassenspezifischen Funktionen /
Methoden - Erweiterte Möglichkeiten gegenüber struct
- Konstruktoren / Destruktoren
- Ăśberladen von Funktionen (Methoden) und
Konstruktoren - Ăśberladen von Operatoren
- Neu
- Effiziente Wiederverwendbarkeit
- dazu ? Vererbung
3Kapitel 11 Vererbung
Modellierung von Objekten mit geringen
Unterschieden
- Bisherige Mittel zum Modellieren von ähnlichen
Objekten - Sei Klasse A bereits definiert (Beispiel
Sparkonten, Kap. 9). - Wir wollen jetzt Girokonten modellieren ? Klasse
B.
- Ansatz
- Kopiere Code von Klasse A
- Umbenennung in Klasse B
- Hinzufügen, ändern, entfernen von Attributen und
Methoden
- Probleme
- Aufwändig bei Änderungen (z.B. zusätzlich
Freistellungsbetrag für alle Konten) - Fehleranfällig
und langweilig!
4Kapitel 11 Vererbung
Alternative Vererbung
- Seien A und B Klassen
- A ist Oberklasse von B bzw. B ist
Unterklasse von A - Wir sagen B erbt Attribute und Methoden von A
d.h. B kennt Attribute und Methoden von A
(Grad der Bekanntschaft wird gleich noch
detailliert angegeben) - B fĂĽgt neue Attribute und Methoden zu denen von
A hinzu ? ggf. werden (alte) Methoden neu
definiert - Jede Instanz von B ist auch eine Instanz von A
5Kapitel 11 Vererbung
Beispiel Klassen KString und KVersalien
- Definiere Klasse KString
- Attribute
- Zeichenkette
- Länge
- Methoden
- Konstruktor / Destruktor
- SetValue, GetValue, Length, Print
- Betrachte Unterklasse KVersalien
- FĂĽr Zeichenketten, die Buchstaben nur als
GroĂźbuchstaben aufweisen!
6Kapitel 11 Vererbung
Klasse KString 1. Versuch
class KString private char mValue int
mLength public KString(char s) bool
SetValue(char s) char GetValue() int
Length() void Print() KString()
schon ganz gut, aber
Zugriffsspezifikation private wird Probleme
machen! ? siehe später!
7Kapitel 11 Vererbung
Grundansatz Vererbung
class KVersalien public KString
Name der Unterklasse
Unterklasse KVersalien erbt von der Oberklasse
KString Attribute und Methoden von KString sind
in KVersalien (bedingt) verfĂĽgbar!
public besagt an dieser Stelle Ăśbernahme der
Zugriffsspezifikationen von der Oberklasse (hier
von KString)
8Kapitel 11 Vererbung
Grundansatz Vererbung
class KVersalien public KString public
KVersalien(char s) // Eigener Konstruktor
bool SetValue(char s) // Ăśberschriebene
Methode void Print() //
Ăśberschriebene Methode
- KVersalien möchte von KString erben
- Attribute mValue und mLength
- Methoden GetValue und Length
- Destruktor
9Kapitel 11 Vererbung
Verfeinerung des Grundansatzes
- Zwei Arten des Verbergens
- Geheimnis (auch) vor KindernKlasse möchte
Attribute und Methoden exklusiv fĂĽr sich behalten
und nicht beim Vererben weitergeben? Wahl der
Zugriffsspezifikation private - FamiliengeheimnisseAttribute und Methoden
werden nur den Erben (und deren Erben
usw.)bekannt gemacht, nicht aber
AuĂźenstehenden? Wahl der Zugriffsspezifikation
protected
10Kapitel 11 Vererbung
Klasse KString 2. Versuch
class KString protected char mValue int
mLength public KString(char s) bool
SetValue(char s) char GetValue() int
Length() void Print() KString()
11Kapitel 11 Vererbung
Erste Zusammenfassung
- Alle als public oder protected zugreifbaren
Komponenten sind fĂĽr Erben sichtbar. - Die als private charakterisierten Komponenten
sind in ihrer Sichtbarkeit auf die Klasse selbst
beschränkt.
12Kapitel 11 Vererbung
Sprachliche Regelung Der Vorgang des Erzeugens
einer Unterklasse aus einer Oberklasse durch
Vererbung nennen wir ableiten. Hier Klasse
KVersalien wird von der Klasse KString abgeleitet.
sorgt fĂĽr die soeben zusammengefassten
Zugriffsregeln beim Vererben
class KVersalien public KString public
KVersalien(char s) // Eigener Konstruktor
bool SetValue(char s) // Ăśberschriebene
Methode void Print() //
Ăśberschriebene Methode
Man sagt auch public-Ableitung (zur
Unterscheidung )
13Kapitel 11 Vererbung
Weitere Formen der Ableitung
- public-Ableitung Oberklasse public ?
Unterklasse public Oberklasse protected ?
Unterklasse protected Oberklasse private ?
Unterklasse nicht verfĂĽgbar - protected-Ableitung Oberklasse public ?
Unterklasse protected Oberklasse protected ?
Unterklasse protected Oberklasse private ?
Unterklasse nicht verfĂĽgbar - private-Ableitung Oberklasse public ?
Unterklasse private Oberklasse protected ?
Unterklasse private Oberklasse private ?
Unterklasse nicht verfĂĽgbar
14Kapitel 11 Vererbung
Implementierung der Klasse KString
include ltiostreamgt include ltcstringgt include
"KString.h" using namespace std KStringKStrin
g(char s) mLength strlen(s) // Länge
ohne terminale '\0' mValue new
charmLength1 // 1 fĂĽr '\0'-Zeichen!
strcpy(mValue, s) // kopiert auch
terminale '\0' KStringKString() delete
mValue mLength -1
Fortsetzung auf nächster Folie
15Kapitel 11 Vererbung
Fortsetzung
int KStringLength() return mLength void
KStringPrint() cout ltlt mValue ltlt
endl char KStringGetValue() return
mValue bool KStringSetValue(char s) int
length strlen(s) if (length gt mLength)
return false strcpy(mValue, s) mLength
length return true
16Kapitel 11 Vererbung
Implementierung der abgeleiteten Klasse KVersalien
include ltiostreamgt include ltctype.hgt include
"KVersalien.h" using namespace
std KVersalienKVersalien(char s)
KString(s) for (int i 0 i lt mLength i)
if (islower(mValuei)) mValuei
toupper(mValuei)
- Ablauf
- Zuerst wird Konstruktor von KString
aufgerufen,d.h. nach Speicherallokation wird
Zeichenkette nach mValue kopiert und mLength wird
gesetzt. - Danach wird Code im Konstruktor von KVersalien
ausgefĂĽhrt.
17Kapitel 11 Vererbung
Implementierung der abgeleiteten Klasse
KVersalien (Fortsetzung)
void KVersalienPrint() cout ltlt
"KVersalienPrint -gt " ltlt endl
KStringPrint() bool KVersalienSetValue(cha
r s) if (!KStringSetValue(s)) return
false for (int i 0 i lt mLength i)
if (islower(mValuei)) mValuei
toupper(mValuei) return true
Methoden Length(),GetValue() und der Destruktor
werden von der Eltern- / Oberklasse geerbt !
? Implementierung fertig!
18Kapitel 11 Vererbung
Testumgebung
include ltiostreamgt include "KString.h" include
"KVersalien.h" using namespace std int main()
KString s new KString("aBraCaDaBra") s-gtPrin
t() KVersalien v new KVersalien(s-gtGetValue()
) v-gtPrint() s-gtSetValue("CUl8er") s-gtPrint()
v-gtSetValue(s-gtGetValue()) v-gtPrint() delete
s delete v
19Kapitel 11 Vererbung
Ausgabe
20Kapitel 11 Vererbung
- Sprachregelungen
- Oberklassen werden Elternklassen, manchmal auch
Vaterklassen genannt. - Unterklassen sind von Elternklassen abgeleitete
Klassen. - Abgeleitete Klassen werden manchmal auch
Tochterklassen genannt. - Die Methoden aus Elternklassen können in den
abgeiteten Klassen ĂĽberschrieben oder
redefiniert werden.
- Zweite Zusammenfassung
- Häufigste Form der Ableitung ist die
public-Ableitung class Bpublic A - Methoden der Elternklassen können benutzt oder
ĂĽberschrieben werden, sofern sie in der
Elternklasse public bzw. protected sind. - Überschriebene Methoden der Elternklasse können
explizit durch Angabe der Elternklasse aufgerufen
werden (Bsp KStringSetValue).
21Kapitel 11 Vererbung
Vererbung bisher
hier einfache Vererbung (nur eine Oberklasse)
22Kapitel 11 Vererbung
BeispielEinfache Klassenhierachie
class Person private KString Vorname
Frau Mutter Mann Vaterpublic
Person(char vorname) Person(KString
vorname) char Name() void
SetzeVater(Mann m) void SetzeMutter(Frau
f) void Druck() Person()
Klasse Person enthält alle Attribute und
Methoden, die geschlechtsunspezifisch sind.
23Kapitel 11 Vererbung
Beispiel Klassenhierachie
class Mann public Person private Frau
Ehefraupublic Mann(char vn) Mann(Person
p) void NimmZurFrau(Frau f) Frau
EhemannVon()
class Frau public Person private Mann
Ehemannpublic Frau(char vn) Frau(Person
p) void NimmZumMann(Mann m) Mann
EhefrauVon()
Die abgeleiteten Klassen Mann und Frau enthalten
alle Attribute und Methoden, die
geschlechtsspezifisch sind.
24Kapitel 11 Vererbung
Problem Zirkularität
FĂĽr Klasse Mann mĂĽssen die Klassen Person und
Frau bekannt sein!
FĂĽr Klasse Frau mĂĽssen die Klassen Person und
Mann bekannt sein!
FĂĽr Klasse Person mĂĽssen die Klassen Mann und
Frau bekannt sein!
A ? B bedeutetA wird von B benötigt
25Kapitel 11 Vererbung
Lösung Vorwärtsdeklaration (wie bei Funktionen)
- bei Funktionen z.B. void Funktionsname(int
x)
- bei Klassen z.B. class Klassenname
26Kapitel 11 Vererbung
Zwei Konstruktoren
PersonPerson(KString vn) Vater(0), Mutter(0)
Vorname new KString(vn-gtGetValue()) Pers
onPerson(char vn) Vater(0), Mutter(0)
Vorname new KString(vn)
27Kapitel 11 Vererbung
char PersonName() return
Vorname-gtGetValue()
Vorname ist private!
Name() ist public!
void PersonSetzeMutter(Frau f) Mutter
f void PersonSetzeVater(Mann m) Vater
m
28Kapitel 11 Vererbung
void PersonDruck(char s) cout ltlt s ltlt
"Vorname " ltlt Vorname-gtGetValue() ltlt endl if
(Mutter ! 0) cout ltlt s ltlt "Mutter "
Mutter-gtDruck("") if (Vater ! 0)
cout ltlt s ltlt "Vater " Vater-gtDruck("")
29Kapitel 11 Vererbung
MannMann(Person p) Person(p-gtName()),
Ehefrau(0) MannMann(char vn) Person(vn),
Ehefrau(0) void MannNimmZurFrau(Frau f)
Ehefrau f Frau MannEhemannVon()
return Ehefrau
FrauFrau(Person p) Person(p-gtName()),
Ehemann(0) FrauFrau(char vn) Person(vn),
Ehemann(0) void FrauNimmZumMann(Mann m)
Ehemann m Mann FrauEhefrauVon()
return Ehemann
30Kapitel 11 Vererbung
Hilfsroutinen
void Verheirate(Mann m, Frau f) if (m ! 0
f ! 0) m-gtNimmZurFrau(f)
f-gtNimmZumMann(m)
Bemerkung Schlampige Programmierung, weil man
vorher noch testen mĂĽsste, ob beide Personen
ledig sind!
void Scheide(Mann m, Frau f) if
(m-gtEhemannVon() f) m-gtNimmZurFrau(0)
f-gtNimmZumMann(0)
Bemerkung Schlampige Programmierung, weil
ja, warum?
31Kapitel 11 Vererbung
Testprogramm
int main() Mann Anton new Mann("Anton")
Frau Bertha new Frau("Bertha") Mann Carl
new Mann("Carl") Carl-gtSetzeMutter(Bertha)
Carl-gtSetzeVater(Anton) Frau Doris new
Frau("Doris") Doris-gtSetzeMutter(Bertha)
Doris-gtSetzeVater(Anton) Anton-gtDruck("A ")
Bertha-gtDruck("B ") Carl-gtDruck("\tC")
Doris-gtDruck("\tD") Verheirate(Anton,
Bertha) Bertha-gtEhefrauVon()-gtDruck("B ist
Frau von ") Anton-gtEhemannVon()-gtDruck("A ist
Mann von ") delete Doris delete Carl
delete Bertha delete Anton
32Kapitel 11 Vererbung
Ausgabe
A Vorname Anton B Vorname Bertha
CVorname Carl CMutter Vorname
Bertha CVater Vorname Anton
DVorname Doris DMutter Vorname
Bertha DVater Vorname Anton B ist
Frau von Vorname Anton A ist Mann von Vorname
Bertha
33Kapitel 11 Vererbung
Abstrakte Klassen
ein paar Bemerkungen vorab
hier
- Klasse Person dient nur als Behälter für
Gemeinsamkeiten der abgeleiteten Klassen Mann
und Frau - Es sollen keine eigenständigen Objekte dieser
Klassen instantiiert werden! Hier wäre es
jedoch möglich Person p(Fred)
? Man kann erzwingen, dass abstrakte Klassen
nicht instantiiert werden können! ?
nächstes Kapitel (u.a.)