PKJ 2005/1Stefan Dissmann
Rückblick: Liste und Element
public class IntElement {
private int wert;
private IntElement nachfolger;
public IntElement(int w) {
wert = w;
nachfolger = null;
}
public void verkette(IntElement n) {
nachfolger = n;
}
}
PKJ 2005/2Stefan Dissmann
Rückblick: Liste und Element
public class IntListe {
private IntElement anfang, ende;
public IntListe() {…};
public void fügeAn(int w) {…};
public int gibErstes() {…};
public void löscheErstes() {…};
public boolean leer() {…};
}
PKJ 2005/3Stefan Dissmann
Lösungen zu Übungsblatt 8
Musterlösungen zu zwei Teilaufgaben der Übung 8:
l) Schreiben Sie eine Methode verlängere, die eine Kopie einer als Parameter übergebenen Liste an die bestehende Liste anhängt. Die übergebene Liste soll dabei unverändert bleiben.
o) Schreiben Sie eine Methode lösche mit einer ganzen Zahl als Parameter. Diese Methode soll in der Liste alle Werte löschen, die dem übergebenen Wert entsprechen. Beachten Sie alle Sonderfälle!
PKJ 2005/4Stefan Dissmann
Lösungen zu Übungsblatt 8
public void verlängere(IntListe il) {
IntListe neu = il.kopiere();
if (!leer()) {
ende.verkette(neu.anfang);
} else {
anfang = neu.anfang;
}
ende = neu.ende;
größe = größe + neu.größe; // aus e)
}
PKJ 2005/5Stefan Dissmann
Lösungen zu Übungsblatt 8
public void verlängere(IntListe il) {
IntListe neu = il.kopiere();
if (!leer()) {
ende.verkette(neu.anfang);
} else {
anfang = neu.anfang;
}
ende = neu.ende;
größe = größe + neu.größe; // aus e)
}
il unverändert lassen!
PKJ 2005/6Stefan Dissmann
Lösungen zu Übungsblatt 8
public void verlängere(IntListe il) {
IntListe neu = il.kopiere();
if (!leer()) {
ende.verkette(neu.anfang);
} else {
anfang = neu.anfang;
}
ende = neu.ende;
größe = größe + neu.größe; // aus e)
}
Kapselung???
PKJ 2005/7Stefan Dissmann
Kapselung in JAVA
Objekt in JAVAentspricht nicht der intuitiven Vorstellung einer
Kapsel.
Kapselung und Geheimnisprinzip (private)gelten nur für Objekte aller anderen Klassen.
Objekte der eigenen Klasse haben freien Zugang zu allen privaten Attributen und Methoden.Daher im Bsp. möglich: ende = neu.ende;
PKJ 2005/8Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) {…}
Probleme: • In leerer Liste kein Löschen.• Referenzen auf Anfang und Ende korrigieren.• Wenn Element gelöscht wird, Vorgänger mit Nachfolger verbinden.
Besonderes Problem:Wenn ein Element erreicht ist, gibt es keinen Weg zurück zum
Vorgänger.
deshalb: von Vorgänger ausgehend Nachfolger „inspizieren“.
PKJ 2005/9Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
PKJ 2005/10Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
nur wenn nicht leer!
PKJ 2005/11Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
nur wenn >= 2 Elemente!
PKJ 2005/12Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
für fast alle Elemente!
PKJ 2005/13Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
Treffer!
PKJ 2005/14Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
Kein Treffer!
PKJ 2005/15Stefan Dissmann
Lösungen zu Übungsblatt 8
public void lösche(int w) { if (!leer()) { if (anfang != ende) { IntElement lauf = anfang; while (lauf != ende) { if (lauf.gibNachfolger().gibWert() == w) { if (lauf.gibNachfolger() == ende) { ende = lauf; } lauf.verkette(lauf.gibNachfolger().gibNachfolger()); größe--; } else { lauf = lauf.gibNachfolger(); } } } if (gibErstes() == w) { löscheErstes(); größe--; // aus e)} } }
Und noch das erste Element!
PKJ 2005/16Stefan Dissmann
Weitere Methode für IntListe
Aufgabe:Die Methode void zweimal() soll eine Liste einmal um sich selbst verlängern, so dass anschließend alle Elemente zweimal in der gleichen Reihenfolge auftreten.
PKJ 2005/17Stefan Dissmann
Weitere Methode für IntListe
Aufgabe:Die Methode void zweimal() soll eine Liste einmal um sich selbst verlängern, so dass anschließend alle Elemente zweimal in der gleichen Reihenfolge auftreten.
Lösung:Sieht einfach aus, da wir ja schon verlängere als Methode haben.
PKJ 2005/18Stefan Dissmann
Weitere Methode für IntListe
Aufgabe:Die Methode void zweimal() soll eine Liste einmal um sich selbst verlängern, so dass anschließend alle Elemente zweimal in der gleichen Reihenfolge auftreten.
Lösung: public class IntListe {
public void zweimal() {
verlängere(ich-selbst);
}
…
}
PKJ 2005/19Stefan Dissmann
Weitere Methode für IntListe
Aufgabe:Die Methode void zweimal() soll eine Liste einmal um sich selbst verlängern, so dass anschließend alle Elemente zweimal in der gleichen Reihenfolge auftreten.
Lösung: public class IntListe {
public void zweimal() {
verlängere(this);
}
…
}
PKJ 2005/20Stefan Dissmann
Referenz this
Anmerkungen:• this ist in jeder Klasse verfügbar.• this ist eine Referenz auf das durch die Klasse definierte
Objekt.
this
PKJ 2005/21Stefan Dissmann
Referenz this
Anmerkungen:• this ist in jeder Klasse verfügbar.• this ist eine Referenz auf das durch die Klasse definierte
Objekt.
• this kann auch benutzt werden, um Namenskonflikte zu lösen:
private IntElement anfang, ende;public IntListe(int w) {
anfang = ende = new IntElement(w);}
this
So bekannt!
PKJ 2005/22Stefan Dissmann
Referenz this
Anmerkungen:• this ist in jeder Klasse verfügbar.• this ist eine Referenz auf das durch die Klasse definierte
Objekt.
• this kann auch benutzt werden, um Namenskonflikte zu lösen:
private IntElement anfang, ende;public IntListe(int anfang) { this.anfang = ende = new IntElement(anfang);}
this
w anfang
PKJ 2005/23Stefan Dissmann
Kritische Betrachtung
Defizite unserer IntListe:
• Durch die einseitige Richtung der Verkettung werden „vorausschauende“ Algorithmen benötigt.
• Manche Operationen sind sehr aufwändig, z.B. alle von hinten beginnenden Durchläufe.
PKJ 2005/24Stefan Dissmann
Kritische Betrachtung
Defizite unserer IntListe:
• Durch die einseitige Richtung der Verkettung werden „vorausschauende“ Algorithmen benötigt.
• Manche Operationen sind sehr aufwändig, z.B. alle von hinten beginnenden Durchläufe.
Lösung:Verkettung in beide Richtungen doppelt verkettete Liste
PKJ 2005/25Stefan Dissmann
Doppelt verkettete Liste: IntElement2
public class IntElement2 {
private int wert;
private IntElement2 vorgänger, nachfolger;
public IntElement2(int w) {
wert = w;
vorgänger = nachfolger = null;
}
…
}
PKJ 2005/26Stefan Dissmann
Doppelt verkettete Liste: IntElement2
public class IntElement2 {
private int wert; private IntElement2 vorgänger, nachfolger;
public IntElement2(int w) {
wert = w; vorgänger = nachfolger = null;
}
public void verkette(IntElement2 n) { if (n != null) { nachfolger = n; n.vorgänger = this; } } public IntElement2 gibVorgänger() { return vorgänger; }
public IntElement2 gibNachfolger() { return nachfolger; }
public int gibWert() { return wert; }
}
PKJ 2005/27Stefan Dissmann
Kritische Betrachtung (Fortsetzung)
Bisher implementiert:Liste für Werte des Typs int
• Liste für double • Liste für Studierende• Liste von Listen von int
Erfordern jeweils neue, fast identische Implementierung der Klassen für Elemente und Liste.
PKJ 2005/28Stefan Dissmann
Kritische Betrachtung (Fortsetzung)
Analyse:• Elemente haben immer Referenzen auf Vorgänger und
Nachfolger.• Liste verknüpft, löscht und durchläuft immer Elemente.
• Elemente unterscheiden sich im Typ der abgelegten Werte.• Liste benötigt möglicherweise typspezifische Vergleiche.
Idee:Elemente und Liste allgemein formulieren undanschließend nur an wenigen Stellen spezialisieren.
PKJ 2005/29Stefan Dissmann
Vererbung
Das Spezialisieren von allgemeinen Klassen wird ermöglicht durch das
Konzept der Vererbung
PKJ 2005/30Stefan Dissmann
Vererbung
Wenn eine Klasse A die Klasse B spezialisiert,Also die Klasse A von der Klasse B erbt,übernimmt sie alle Attribut- und Methoden-Deklarationen von
B.
A heißt dannUnterklasse von B oder Subklasse von B
B heißt dannOberklasse von A oder Superklasse von A
PKJ 2005/31Stefan Dissmann
Vererbung
Beispiel:
public class Person { private String name, vorname; public Person(String n, String v) { name = n; vorname = v; } public String toString() { return name + ", " + vorname }}
PKJ 2005/32Stefan Dissmann
Vererbung
Beispiel:
public class Person { private String name, vorname; public Person(String n, String v) { name = n; vorname = v; } public String toString() { return name + ", " + vorname }}
public class Kunde extends Person {{ private int nummer;}
PKJ 2005/33Stefan Dissmann
Vererbung
Beispiel:
public class Person { private String name, vorname; public Person(String n, String v) { name = n; vorname = v; } public String toString() { return name + ", " + vorname }}
public class Kunde extends Person { private int nummer;}
PKJ 2005/34Stefan Dissmann
Vererbung
public class Kunde extends Person {{ private int nummer;}
bedeutet:
• Kunde wird als Unterklasse von Person definiert.• Person wird dadurch Oberklasse von Kunde.• Kunde hat geerbt:
• die öffentliche Methode toString,• die privaten Attribute name und vorname.
• In Kunde wird definiert:• das private Attribut nummer.
PKJ 2005/35Stefan Dissmann
Fragen
Was geht wie in der Klasse Kunde?
• Zugriff auf die geerbten privaten Attribute name und vorname.
• Gemeinsame Ausgabe aller drei Attribute.• Definition eines Konstruktors für alle drei Attribute.• Zulässigkeit von Referenzen auf Ober- und Unterklasse.
PKJ 2005/36Stefan Dissmann
Fragen
Was geht wie in der Klasse Kunde?
• Zugriff auf die geerbten privaten Attribute name und vorname.
• Gemeinsame Ausgabe aller drei Attribute.• Definition eines Konstruktors für alle drei Attribute.• Zulässigkeit von Referenzen auf Ober- und Unterklasse.
Antworten:
nächste Woche