Vererbung Themen derÜbung Rücksprachen

Transcription

Vererbung Themen derÜbung Rücksprachen
Themen der Übung
Themen heute
Evaluation
Rücksprachen
Vererbung
IDEs – Eclipse & Netbeans
Packages, innere Klassen
CoMa-Übung XI
Vererbung, Generics
Interfaces
TU Berlin
Enums
16.01.2013
Evaluation
Heute bekommt ihr Evaluationsbögen zur CoMa-Übung.
Nutzt Kommentare, schreibt, was euch gut gefällt oder euch nicht
gefällt.
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
1 / 47
CoMa-Übung XI (TU Berlin)
Rücksprachen
Rücksprachen (2)
Ablauf
Zur Vorbereitung:
Vererbung
16.01.2013
30 min bei einem Tutor oder Assistenten.
Wiederholungs-Übungstermine am 4. und 5. Februar.
Finden in der letzten Vorlesungswoche (11.2.-15.2.) statt.
Beantwortung von Fragen, Wiederholung von Stoff.
Termine werden über Listen im Sekretariat verteilt.
Fragen / Wünsche per Mail an Martin oder am 4. / 5. mitbringen.
2 / 47
Die Listen liegen noch NICHT aus.
Ankündigung auf der HP & in der Vorlesung, wenn sich das ändert.
Proberücksprachen
Öffentliche Rücksprachen am 6.2. in der Übung.
Öffentliche Rücksprachen sind Freiversuche
Themen
Alles seit dem Zwischentest:
I
Datenstrukturen: Arrays, Listen, Queues, Stacks
I
Anmeldung per Mail an Martin oder in den Übungen am 4. & 5.
Rekursion
Vererbung
Landau-Notation, Kürzeste Wege, Sortieralgorithmen
I
Bei Nicht-Bestehen der Rücksprache:
Wiederholungs-Rücksprache bei einem Assistenten in der ersten & zweiten
Woche der Semesterferien.
Definitionen und Ideen, keine Beweise
CoMa-Übung XI (TU Berlin)
Bei Nicht-Bestehen habt ihr trotzdem noch 2 Chancen.
Meldet euch aber bitte nur, wenn ihr euch vorbereiten wollt. ;)
Vererbung
16.01.2013
3 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
4 / 47
IDEs
Packages
IDEs (Integrated Development Environments)
Editoren zum Schreiben von Java-Programmen mit vielen
Hilfs-Features (für PA 11 hilfreich).
Viele kostenlos & für die meisten Systeme verfügbar.
Beispiele: Eclipse (http://eclipse.org/) & Netbeans
(http://netbeans.org/)
Eclipse Einführung
http://www.javakurs-online.de/part04.html
Netbeans Einführung
http://home.edvsz.fh-osnabrueck.de/skleuker/querschnittlich/
NetbeansNutzung.pdf
Sehr ausführliches, komplett bebildertes Handbuch (Kapitel 3).
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
5 / 47
Innere Klassen
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
6 / 47
Vererbung – Eigenschaften
Eigenschaften:
“Ist-eine-Art-von”-Beziehung
Vererbung erweitert / spezialisiert
Bsp: Jeder Studierender ist ein Mensch (aber nicht umgekehrt)
Studenten haben Attribute, die andere Menschen nicht haben (z.B.
Matrikelnummern)
Notation:
class Student extends Mensch {
private int matrikelnummer;
}
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
7 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
8 / 47
Vererbung – Typen
Vererbung – Test auf Typen
Typen:
Test auf Typen:
Wir nehmen jetzt an, dass Student von Mensch erbt, und Mensch
direkt von Object
Ein Student-Objekt ist vom Typ Student und Mensch (sowie von
allen Oberklassen von Mensch)
Wird bei einer Klasse kein extends angegeben, geht der Compiler
von extends Object aus
I
I
I
I
Ein Objekt vom Typ Mensch, lässt sich mit instanceof of seinen
Typ testen
Jede Klasse hat Object als Oberklasse
Jede Klasse hat Methoden wie toString() und equals()
Object ist die einzige Klasse ohne Oberklasse
Vererbungshierarchie ist ein Baum (keine Mehrfachvererbung)
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
Beispiel: Mensch mensch;
I
I
I
9 / 47
Vererbung – Sichtbarkeit
(mensch instanceof Student) ist false
(mensch instanceof Mensch) ist true
(mensch instanceof Object) ist true
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
10 / 47
Vererbung – Designregeln
Regeln:
Sichtbarkeits-Modifizierer:
A hat ein B (z.B. ein Student hat Matrikelnummer)
Es gibt private, <nichts>, protected, public
A bekommt ein Datenfeld vom Typ B
private: Sichtbar innerhalb der Klasse
A ist von der Art B (z.B. ein Student ist ein Mensch)
<nichts>: Sichtbar innerhalb der Package
A wird von B abgeleitet
protected: Sichtbar innerhalb der Package und in abgeleiteten
Klassen
A verhält sich wie B / A hat die Eigenschaft B (z.B. Studenten sind
nach Matrikelnummern sortierbar)
public: Überall sichtbar
A implementiert Interface B
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
11 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
12 / 47
Vererbung – Designregeln
Generics – Vorteile & Deklaration
Vorteile bisher:
Ermöglichen parametrisierte Klassen (z.B. List<T>)
Regeln:
Super, wenn Klassen nichts über T wissen müssen (Listen, Queues,
Stacks, ...)
Nicht immer eindeutig, Bsp. Quadrat und Rechteck
Variante 1: Jedes Quadrat ist eine spezialisiertes Rechteck → leite
Quadrat von Rechteck ab
Variante 2: Ein Rechteck hat 2 Seitenlängen, ein Quadrat nur ein →
Rechteck erweitert Quadrat, leite Quadrat von Rechteck ab
Variante 3: Rechteck und Quadrat sind beides Vielecke → leite beide
von Vieleck ab
Richtig und falsch gibt es nicht immer
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
13 / 47
Generics – Deklaration
Deklaration:
Parametrisierte Typen für Klassen (z.B. List<T>)
Parametrisierte Typen für Methoden, z.B.
public class Util {
public <T> T random( T m, T n ) {
return Math.random() > 0.5 ? m :
}
}
CoMa-Übung XI (TU Berlin)
n;
Vererbung
16.01.2013
14 / 47
Generics – Deklaration
Deklaration:
Variante 1:
public class Util {
public <T> T random( T m, T n ) {
return Math.random() > 0.5 ? m :
}
}
Variante 2:
public class Util<T> {
public T random( T m, T n ) {
return Math.random() > 0.5 ?
}
}
m :
Deklaration:
Variante 3:
public class Util<T> {
public <T> T random( T m, T n ) {
return Math.random() > 0.5 ? m :
}
}
n;
n;
Würde auch gehen, aber unschön & unnötig
n;
Typ-Parameter der Klasse wird in der Methode überschrieben
Beide Varianten funktionieren
Nur in einer Methode gebraucht → nur dort deklarieren
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
15 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
16 / 47
Generics – Typanpassung
Generics – Type Erasure
Konzept:
Effekt:
Generics lassen sich umgehen:
List<Integer> intList = ...;
List list = intList;
list.add(‘‘Hallo Welt!’’);
Parametrisierte Typen existieren nur für den Kompiler
Zur Laufzeit nicht
Folgen:
Haben den Typ der Liste angepasst bzw. vergessen
if (list instanceof List<String>) funktioniert nicht
Compiler warnt (zu recht), aber kein Compilefehler
if (list instanceof List) schon, sagt aber nichts über den
Typ-Parameter
Generics nicht umgehen!
.getClass() hilft auch nicht für Typ-Parameter List<Integer>
intList = ...;
List<String> strList = ...;
boolean b = (intList.getClass() == strList.getClass());
//ergibt true
Bemerkung:
Jeder Integer ist auch ein Object
Das hier:
List<Integer> intList = ...;
List<Object> list = intList;
gibt aber einen Compile-Fehler wegen obiger Situation
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
17 / 47
Generics – Raw-Typen
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
18 / 47
Generics – Der unbekannte Typ ?
Implizit:
Man kann Generics weglassen (z.B. List statt List<String>)
Unterschied zwischen ? und Object:
Der Typ-Parameter hat dann den unbekannten Typ
LinkedList<Object> list = new LinkedList<Integer>();
Praktisch ist dann Object der Typ-Parameter
Fehler (wie eben)
Explizit:
LinkedList<?> list = new LinkedList<Integer>();
Will man explizit einen unbekannten Typ: List<?>
Erlaubt
? steht für den unbekannten Typ
Vorteil: Compiler weiß, dass der Typ-Parameter nicht vergessen wurde
→ Keine Warnung deswegen
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
19 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
20 / 47
Generics – Typen
Generics – Eingeschränkte Typen
Typ-Inferenz:
Typ-Einschränkung:
Neue Methode für Util:
public class Util {
public static <T> T max( T m, T n ) {
return (m > n) ? m : n;
}
}
Geht so nicht → > nur für primitive Zahltypen definiert
Das Interface Comparable<T> stellt eine Methode int compareTo(T
t) für vergleichbare Objekte bereit
Besser, geht aber immer noch nicht:
public class Util {
public static <T> T max( T m, T n ) {
return (m.compareTo(n) > 0) ? m :
}
}
CoMa-Übung XI (TU Berlin)
Vererbung
So geht es:
public class Util {
public static <T extends Comparable<T>> T max( T m,
T n ) {
return (m.compareTo(n) > 0) ? m : n;
}
}
<T extends Comparable<T>> erzwingt, dass nur Typen T
zugelassen werden, die mit sich selbst vergleichbar sind
Typen, die mit irgendwas anderem vergleichbar sind, reichen dafür
nicht nicht
<T extends Comparable<?>> geht daher nicht
n;
16.01.2013
21 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
22 / 47
Beispiel mit extends, super, ?
Generics – Eingeschränkte Typen
max-Methode:
Methode von eben erlaubt alles mit sich selbst vergleichbare public
class Util {
public static <T extends Comparable<T>> T max( T m,
T n ) {
return (m.compareTo(n) > 0) ? m : n;
}
}
Stellt euch vor, wir haben
Typ-Einschränkung mit extends
extends erlaubt es, einen Typ-Parameter einzuschränken auf
I
I
Unterklassen einer vorgegebenen Klasse
Klassen, die bestimmte Interfaces implementieren
Kombinierbar: <T extends Comparable<T> & Cloneable>
erfordert, dass
I
I
T das Interface Comparable<T> implementiert
und das Interface Cloneable implementiert.
I
Typ-Einschränkung mit super
I
I
super erlaubt es, einen Typ-Parameter einzuschränken auf
I
Oberklassen einer vorgegebenen Klasse
Klassen Obst und Apfel
Apfel erbt von Obst
Apfel implementiert Comparable<Obst> → (Vergleich auf
Vitamingehalt, ...)
Apfel nicht direkt mit sich selbst vergleichbar
max(apfel1,apfel2) geht daher nicht
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
23 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
24 / 47
Beispiel mit extends, super, ?
Generische Arrays erstellen
max-Methode – Lösung:
Beobachtung: T[] test = new T[3]; geht nicht
Neue Methode:
public class Util {
public static <T extends Comparable<? super T>> T
max( T m, T n ) {
return (m.compareTo(n) > 0) ? m : n;
}
}
Problem: Infos über den Typ von T zur Laufzeit nicht mehr vorhanden
Lösung: den Typ von T selbst speichern!
Datentyp für Typen
Ein Objekt der Klasse Class<T> stellt den Typ T dar
Objekt ist mittels Classname.class zu finden (z.B. String.class)
Gibts auch für Arrays eines Typs: Classname[].class (z.B.
String[].class)
Erlaubt alles mit einer Oberklasse von sich vergleichbare
max(apfel1,apfel2) geht
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
25 / 47
CoMa-Übung XI (TU Berlin)
Generische Arrays erstellen
Interfaces & Schnittstellen
static <T> T[] createArray(Class<T[]> type, int len) {
return type.cast(
Array.newInstance(type.getComponentType(), len));
}
Idee
I
I
I
Erzeugt ein Array vom gewünschten Typ und Länge und gibt es
zurück
I
Etwas umständlich, funktioniert aber
16.01.2013
26 / 47
A hat die Eigenschaft B
Ein Student hat die Eigenschaft, mit anderen Studenten vergleichbar
zu sein (→ Interface Comparable)
A ist von der Art B
Ein Matrikelnummer-Sortierer für Studenten ist von der Art, ein
Sortierer für Studenten zu sein (→ Interface Comparator)
Mehrere Interfaces pro Klasse → erlaubt eine Art von
Mehrfachvererbung
Methode erfordert import java.lang.reflect.Array;
Vererbung
16.01.2013
Interfaces stellen Beziehungen wie
Methode bekommt einen Typ type und eine Länge len übergeben
CoMa-Übung XI (TU Berlin)
Vererbung
27 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
28 / 47
Interfaces – Deklaration
Interfaces – Beispiel
public interface Comparable<T> {
int MAGIC NUMBER = 4;
boolean compareTo(T t);
Deklaration von Interfaces
Schlüsselwort interface
Sichtbarkeitsmodifizierer (z.B. public )
}
Name: Konvention wie bei Klassen
Deklaration von Interfaces
Generics möglich
Beispiel:
Deklariert ein öffentliches Interface namens Comparable<T>
public interface Comparable<T> {}
Generischer Typ T
Deklariert eine Methode compareTo
Inhalt von Interfaces
I
Keine Konstruktoren
Nur public abstract Methoden
I
I
I
Schlüsselwörter werden automatisch ergänzt → nicht selbst schreiben
Konstante MAGIC NUMBER mit Wert 4
Nur static final Variablen (d.h. Konstanten)
I
Schlüsselwörter werden automatisch ergänzt → nicht selbst schreiben
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
29 / 47
Interfaces – Was nicht geht
I
I
Steht implementierenden Klassen zur Verfügung
Konstante → Großschreiben
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
30 / 47
Interfaces – Markerinterfaces
Verboten
Spezialfall Markerinterfaces
Konstruktoren
Leeres Interface (d.h. ohne Konstanten und Methoden)
Statische Methoden
z.B. public interface Cloneable {}
Methoden, die nicht public sind
Kann mit instanceof getestet werden
Methoden, die nicht abstract sind (d.h. “ausprogrammierte”
Methoden gehen nicht)
z.B. if (object instanceof Cloneable)
→ so kann leicht getestet werden, ob clone()-Aufrufe auf einem
Objekt Sinn machen
Objektvariablen
Klassenvariablen, die nicht final sind
Subinterfaces
Und wenn man das braucht?
Interfaces können erweitert werden mittels extends
Abstrakte Klassen abstract class
z.B. public interface Comparable<T> extends Cloneable {}
Können alles, was Interfaces können
Comparable<T> erhält dann alle Methoden und Konstanten von
Cloneable
Können alles, was Interfaces verboten ist
Nachteil: man kann nur von einer abstrakten Klasse erben
CoMa-Übung XI (TU Berlin)
I
Rückgabewert boolean
Parameter vom Typ T
Implizit public und abstract
Muss von implementierenden Klassen implementiert werden
Vererbung
16.01.2013
31 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
32 / 47
Interfaces – Implementierung
Interfaces – Mehrfachvererbung
Implementierung
Was passiert, wenn zwei Interfaces dieselbe Methode haben?
Schlüsselwort implements
Zusätzlich erbt die Klasse Student von der Klasse Mensch
Beispiel:
public interface Fahrzeug {
void bewegeDich();
}
public interface Lebewesen {
void bewegeDich();
}
public interface LebendesFahrzeug extends Fahrzeug,
Lebewesen {
}
→ man erbt immer von einer Klasse und beliebig vielen Interfaces
Kein Widerspruch → okay
z.B. public class Student extends Mensch implements
Comparable<Student>, Cloneable
Die Klasse Student implementiert die Interfaces
Comparable<Student> und Cloneable
I
public boolean compareTo(Student student) muss
implementiert werden für das Interface Comparable<Student>
F
I
(oder wir machen die Klasse Student abstrakt)
Cloneable ist ein Markerinterface, nichts zu implementieren
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
33 / 47
Interfaces – Mehrfachvererbung
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
34 / 47
Interfaces – Mehrfachvererbung
Was passiert, wenn zwei Interfaces dieselbe Konstante haben?
Was passiert, wenn zwei Interfaces dieselbe Methode haben?
Beispiel:
public interface Fahrzeug {
int MAGIC = 4;
}
public interface Lebewesen {
String MAGIC = ‘‘Huhu’’;
}
public interface LebendesFahrzeug extends Fahrzeug,
Lebewesen {
}
Beispiel:
public interface Fahrzeug {
void bewegeDich();
}
public interface Lebewesen {
boolean bewegeDich();
}
public interface LebendesFahrzeug extends Fahrzeug,
Lebewesen {
}
Für den Compiler okay
Zugriff über Fahrzeug.MAGIC bzw. Lebenwesen.MAGIC
Widerspruch → Compilefehler
I
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
35 / 47
Sonst Compile-Fehler
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
36 / 47
Interfaces – Vorteile
Interfaces – Beispiel
Vorteile von Interfaces
Interface für Sortieralgorithmen:
public interface Sorter<T> {
void sort(List<T> list, Comparator<T> c);
}
Unabhängig von Implementierung
Beschränkung auf das Nötigste
I
I
Leichter wiederzuverwenden
Leicht zu ändern
Interface für Vergleiche:
public interface Comparator<T> {
int compare(T o1, T o2);
}
Noch ein Beispiel
Interface für Sortieralgorithmen:
public interface Sorter<T> {
void sort(List<T> list, Comparator<T> c);
}
Jetzt: 2-dimensionale Objekte nach Fläche oder Umfang sortieren
public abstract class TwoDimensionalObject {
public abstract double area();
public abstract double perimeter();
}
Sortiert eine gegebene Liste
Vergleiche zweier Objekte über einen Comparator<T>
(Java-Interface)
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
37 / 47
Interfaces – Beispiel
Vererbung
16.01.2013
38 / 47
Interfaces – Beispiel
Vergleich basiert auf Fläche:
import java.util.Comparator;
public class AscendingAreaComparator implements
Comparator<TDO> {
public int compare(TDO o1, TDO o2) {
return o1.area() - o2.area();
}
}
Basisklasse für 2-dimensionale Objekte:
public abstract class TDO {
public abstract double area();
public abstract double perimeter();
}
Abgeleitete konkrete Klassen:
public class Rectangle extends TDO {
...
}
import java.util.Comparator;
public class DescendingAreaComparator implements
Comparator<TDO> {
public int compare(TDO o1, TDO o2) {
return o2.area() - o1.area();
}
}
Jetzt: Comparator für Sortieralgos implementieren
CoMa-Übung XI (TU Berlin)
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
39 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
40 / 47
Interfaces – Beispiel
Zusammenfassung
Vergleich basiert auf Umfang:
import java.util.Comparator;
public class AscendingPerimeterComparator implements
Comparator<TDO> {
public int compare(TDO o1, TDO o2) {
return o1.perimeter() - o2.perimeter();
}
}
import java.util.Comparator;
public class DescendingPerimeterComparator implements
Comparator<TDO> {
public int compare(TDO o1, TDO o2) {
return o2.perimeter() - o1.perimeter();
}
}
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
41 / 47
Aufzählungen mit enum
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
42 / 47
16.01.2013
44 / 47
Aufzählungen mit enum
enum erlaubt es, Aufzählungstypen zu definieren
Beispiel: Weiß, Orange, Rot als Typ zum Knotenfärben bei
Tiefensuche
Lässt sich auch über Integer realisieren (0 = Weiß, 1 = Orange, 2
= Rot)
public enum NodeColor {
WHITE, ORANGE, RED;
}
Benutzung der NodeColor-Aufzählung
Deklaration einer Variablen vom Typ NodeColor:
Problem dabei: Kann ungültige Integer-Werte zuweisen (z.B. 3)
NodeColor color;
public enum NodeColor {
WHITE, ORANGE, RED;
}
NodeColor-Werte zuweisen:
color = NodeColor.WHITE;
Deklariert einen öffentlichen Aufzählungstyp NodeColor mit drei
möglichen Werten: WHITE, ORANGE, RED
NodeColor-Werte vergleichen:
Aufzählungstypen (auch Enumerations) genannt sind spezielle Klassen
if (color == NodeColor.WHITE) ...
Vergleiche mit ==, nicht equals
Mögliche Werte eines Aufzählungstyps sind Konstanten →
Großbuchstaben verwenden
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
43 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
Fallunterscheidungen mit enum und switch
Fallunterscheidungen mit enum und switch
switch erlaubt Fallunterscheidungen basierend auf dem Wert einer
Integer- oder Aufzählungsvariable → hier für Aufzählungen
public enum NodeColor {
WHITE, ORANGE, RED;
}
switch (color) {
case WHITE: System.out.println(‘‘Weiß!’’);
break;
case ORANGE: System.out.println(‘‘Orange!’’);
break;
case RED: System.out.println(‘‘Rot!’’); break;
}
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
Wert der Variable color wird unterschieden
NullPointerException wenn color == null ist
Springt zu passenden case, führt Anweisungen aus
Passt kein case, wird zu default gesprungen
break verlässt die switch-Anweisung
45 / 47
Fallunterscheidungen mit enum und switch
switch (color) {
case WHITE: System.out.println(‘‘Weiß!’’);
break;
case ORANGE: System.out.println(‘‘Orange!’’);
break;
case RED: System.out.println(‘‘Rot!’’);
break;
default: System.out.println(‘‘Unbekannt!’’);
}
Bereichsabfragen (0-18, 18-99, ...) sind mit switch nicht möglich
Es werden nur byte, char, short, int und Aufzählungen unterstützt
Ohne break werden nachfolgende Fälle auch abgearbeitet!
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
switch (color) {
case WHITE: System.out.println(‘‘Weiß!’’);
break;
case ORANGE: System.out.println(‘‘Orange!’’);
break;
case RED: System.out.println(‘‘Rot!’’);
break;
default: System.out.println(‘‘Unbekannt!’’);
}
47 / 47
CoMa-Übung XI (TU Berlin)
Vererbung
16.01.2013
46 / 47