3 Generics eine Einführung

Größe: px
Ab Seite anzeigen:

Download "3 Generics eine Einführung"

Transkript

1 21 Das folgende Kapitel erläutert das neue Generics-Konzept anhand eines größeren»intuitiven«beispiels. Es geht hier noch nicht um die genauen theoretischen Einzelheiten, sondern einfach nur darum, ein»gefühl«für die Verwendung von Generics zu entwickeln. Es wird in diesem Kapitel bewusst darauf verzichtet,»fertige«klassen der Klassenbibliothek zu benutzen. Sofern generische Container-Klassen notwendig sind, werden sie selbst geschrieben. In dem Beispiel geht es um Getränke, Getränkeflaschen und Getränkeflaschenkästen. 3.1 Probleme mit Bier- und Weinflaschen Es gibt vielerlei Getränke: Bier, Rotwein, Weißwein etc. Diesen Sachverhalt könnte man etwa in folgender Klassenhierarchie repräsentieren: abstract class Drink { class Beer extends Drink { private final String brewery; public Beer (String brewery) { this.brewery = brewery; public String getbrewery () { return this.brewery; public String tostring () {... abstract class Wine extends Drink { private final String region; public Wine (String region) { this.region = region; public String getregion () { return this.region; public String tostring () {... class WhiteWine extends Wine { public WhiteWine (String region) { super (region); class RedWine extends Wine { public RedWine (String region) { super (region);

2 22 Hier das Klassendiagramm: Drink Beer Wine WhiteWine RedWine Es gibt natürlich auch entsprechende Flaschen: Bierflaschen, Rotweinflaschen, Weißweinflaschen etc. Flaschen kann man füllen und leeren. Auch hier könnte man eine Klassenhierarchie aufbauen: abstract class DrinkBottle { class BeerBottle extends DrinkBottle { private Beer content; public void fill (Beer content) { this.content = content; public Beer empty () { Beer content = this.content; this.content = null; return content; abstract class WineBottle extends DrinkBottle { class WhiteWineBottle extends WineBottle { private WhiteWine content; public void fill (WhiteWine content) { this.content = content; public WhiteWine empty () { WhiteWine content = this.content; this.content = null; return content;

3 3.1 Probleme mit Bier- und Weinflaschen 23 class RedWineBottle extends WineBottle { private RedWine content; public void fill (RedWine content) { this.content = content; public RedWine empty () { RedWine content = this.content; this.content = null; return content; Hier das Klassendiagramm: DrinkBottle BeerBottle WineBottle WhiteWineBottle RedWineBottle Zwar mag es hier im ersten Moment den Anschein haben, als seien fill und empty Methoden, die in den abgeleiteten Klassen überschrieben würden dies ist jedoch nicht der Fall. Die Parametertypen von fill und die Return-Typen von empty sind nämlich jeweils verschieden: Die Klasse BeerBottle z.b. enthält folgende Methoden: public void fill (Beer content) public Beer empty () Die Klasse RedWineBottle aber folgende Methoden: public void fill (RedWine content) public RedWine empty () In jeder instantiierbaren Bottle-Klasse müssen jeweils drei Elemente definiert werden: das content-attribut, die fill-methode und die empty-methode vorausgesetzt, Typsicherheit soll gewährleistet werden. Vorausgesetzt also, dass eine Bierflasche nur mit Bier und eine Weißweinflasche nur mit Weißwein zu füllen sein soll; und weiterhin vorausgesetzt, dass man sicher sein möchte, aus einer Bierflasche Bier zu trinken und aus einer Weißweinflasche Weißwein. Es wäre schöner, wenn man statt einer ganzen Batterie von Flaschenklassen nur eine einzige Flaschenklasse zu definieren brauchte denn die eigentliche

4 24 Funktionalität des Füllens und Leerens ist ja jeweils dieselbe. Der Unterschied der verschiedenen Flaschentypen besteht also nur in der Art des Inhalts und demnach auch in der Art der Parametertypen und der Return-Typen. Man könnte also eine Alternative ausprobieren: class Bottle { private Drink content; public boolean isempty () { return this.content == null; public void fill (Drink content) { this.content = content; public Drink empty () { Drink content = this.content; this.content = null; return content; Dann allerdings wäre man nicht sicher, dass eine Flasche, die für Bier vorgesehen ist, tatsächlich auch Bier beinhalten würde: Bottle beerbottle = new Bottle (); beerbottle.fill (new WhiteWine ("Riesling")); Beer beer = (Beer) beerbottle.empty ();// ClassCastException! Man müsste stets vorher testen: Bottle beerbottle = new Bottle ();... Drink drink = beerbottle.empty (); if (drink instanceof Beer) { Beer beer = (Beer) drink;... Beide oben skizzierten Lösungen die Implementierung per Vererbung und die auf dem Drink-content beruhende Lösung sind diesem Problem also offensichtlich nicht gewachsen. 3.2 Ein generischer Flaschentyp Definition einer generischen Klasse Eine dem Problem angemessene Lösung bedient sich des Konzepts der Generics der Typ-Parametrisierung. Hier eine erste Variante einer solchen Lösung:

5 3.2 Ein generischer Flaschentyp 25 class Bottle<T> { private T content; public boolean isempty () { return this.content == null; public void fill (T content) { if (this.content!= null) throw new IllegalStateException (); this.content = content; public T empty () { if (this.content == null) throw new IllegalStateException (); T content = this.content; this.content = null; return content; public String tostring () { return this.getclass ().getname () + " [content=" + this.content + "]"; Es handelt sich hier um eine Typ-parametrisierte Klasse. In der Überschrift der Klasse wird ein formaler Typ-Parameter namens T eingeführt (der auch als Typ- Variable bezeichet wird): class Bottle<T> { (Statt T hätte man auch den Namen SchallUndRauch wählen können es wird aber empfohlen, formale Typ-Parameter durch ein einziges großes Zeichen zu benennen.) T ist ein»platzhalter«für Beer, WhiteWine oder RedWine (oder für igendwelche andere Klassen). Überall dort, wo in der Vererbungs-Lösung die Namen Beer, WhiteWine oder RedWine benutzt wurden (und wo in der Drink-content-Lösung Drink verwendet wird), kann nun dieser Platzhalter benutzt werden. T steht für irgendeine Klasse. Zunächst wird das content-attribut definiert. Es ist nun nicht mehr vom Typ Beer etc., sondern vom Typ T: private T content; Die fill-methode ist parametrisiert mit einem T-Parameter: public void fill (T content) {... Und empty liefert ein Resultat vom Typ T zurück: public T empty () {... (Und definiert noch eine weitere lokale Variable vom Typ T.)

6 26 Hinweis: Die IllegalStateExceptions werden geworfen, wenn sich eine Flasche nicht in dem für die jeweilige Operation erforderlichen Zustand befindet. Eine volle Flasche kann man nicht füllen und eine leere nicht austrinken. Generierung neuer Typen Wie besorgt man sich nun von dieser Klassendefinition eine Bierflasche (Weißweinflasche, Rotweinflasche)? Zunächst benötigt man eine Referenzvariable, die auf eine Bierflasche zeigen kann: Bottle<Beer> beerbottle; Der Name der hier definierten Referenzvariablen ist beerbottle; ihr Typ ist Bottle<Beer>. Dann muss eine Flasche erzeugt werden, auf die man mit einer Bottle<Beer>- Referenz zeigen kann: new Bottle<Beer> () Zusammengefasst: Bottle<Beer> beerbottle = new Bottle<Beer> (); Eine Flasche, auf die man mit einer Bottle<WhiteWine>-Referenz zeigen kann, wird wie folgt erzeugt: Bottle<WhiteWine> whitewinebottle = new Bottle< WhiteWine > (); Man kann sich die Sache so vorstellen, als habe man im ersten Fall eine Klasse benutzt, in der das T der Bottle-Klasse durch den aktuellen Typ-Parameter Beer ersetzt wurde; im zweiten eine Klasse, in der dieses T durch WhiteWine ersetzt wurde. Tatsächlich existiert aber nur eine einzige parametrisierte Bottle-Klasse. (Dies wird im Kapitel 4»Generics systematisch betrachtet«wesentlich präziser beleuchtet.) Eine Bierflasche kann dann mit Bier gefüllt werden: beerbottle.fill (new Beer ("Veltins")); Einen Versuch, eine Bierflasche mit Weißwein zu füllen: beerbottle.fill (new WhiteWine ("Riesling")); // illegal weist der Compiler zurück. Denn die fill-methode des Typs Bottle<Beer> verlangt einen Parameter, der kompatibel zu Beer ist. Weißwein aber ist kein Bier. Und die Weißweinflasche kann man nur mit Weißwein füllen: whitewinebottle.fill (new WhiteWine ("Riesling"));

7 3.2 Ein generischer Flaschentyp 27 Wenn man eine Bierflasche hat, kann man versuchen, sie zu leeren wenn sie nicht bereits leer ist, ist garantiert, dass man Bier bekommt: Beer beer = beerbottle.empty (); Hier ist kein Downcast erforderlich: Aufgerufen über eine Referenz vom Typ Bottle<Beer>, liefert die empty-methode der Bottle-Klasse eben exakt Beer zurück. Aufgerufen über eine Referenz vom Typ Bottle<WhiteWine>, liefert dieselbe Methode WhiteWine zurück. Bottle ist eine Typ-parametrisierte Klasse eine Klasse, welche offensichtlich die Grundlage ist für konkrete Typen. Bottle<Beer> ist ein solcher konkreter Typ, Bottle<WhiteWine> ein anderer konkreter Typ. Aufgrund der Klasse können beliebige konkrete Typen generiert werden. Hier wird es also wichtig, die Begriffe Klasse und Typ auseinander zu halten. Eine»gewöhnliche«, nicht Typ-parametrisierte Klasse definiert genau einen einzigen Typ eine parametrisierte Klasse ist die Grundlage für die Definition beliebig vieler anderer Typen. Im Folgenden muss es also darum gehen, die konkreten Typen, die aufgrund einer generischen Klasse erzeugt werden können, genauer zu beleuchten insbesondere, was das Problem der Kompatibilität solcher Typen angeht. Kann ein Bottle-Typ generiert werden für Flaschen, die sowohl Rotwein als auch Weißwein enthalten können? Bottle<Wine> winebottle = new Bottle<Wine> (); Das funktioniert obwohl es sich bei Wine um eine abstrakte Klasse handelt. Man kann die winebottle nun sowohl mit Weißwein als auch mit Rotwein füllen: winebottle.fill (new WhiteWine ("Riesling")); Wine wine = winebottle.empty (); System.out.println (wine.getregion ()); winebottle.fill (new RedWine ("Chianti")); wine = winebottle.empty (); System.out.println (wine.getregion ()); Dann kann man natürlich einen Bottle-Typ für solche Flaschen generieren, die sowohl Bier als auch Rot- und Weißwein enthalten können (ob das sinnvoll ist, ist eine andere Frage): Bottle<Drink> drinkbottle = new Bottle<Drink> (); Die fill-methode des Typs Bottle<Drink> gibt sich mit jedem zu Drink kompatiblen Parameter zufrieden; die empty-methode dieses Typs liefert eine Referenz des Typs Drink zurück (der dann u. U. auf Beer downgecastet werden muss): drinkbottle.fill (new Beer ("Jever")); Drink drink = drinkbottle.empty (); Beer beer = (Beer) drink;

8 28 Und man könnte einen noch allgemeineren Bottle-Typ generieren: Bottle<Object> objectbottle = new Bottle<Object> (); In diese hier erzeugte Flasche könnte man auch Benzin einfüllen: objectbottle.fill (new Petrol (...)); Object object = objectbottle.emtpy (); Petrol petrol = (Petrol) object; Man beachte: Die weiter oben entwickelte, auf dem Drink-content basierende Bottle-Klasse verlangte vom content, dass er mindestens Drink-kompatibel ist. Benzin konnte man in Objekte dieser Klasse also nicht einfüllen. Diese für das Problem möglicherweise sinnvolle Einschränkung ist bei der parametrisierten Klasse nicht gegeben! Siehe hierzu aber weiter unten. Kompatibilität Beer ist kompatibel zu Drink, Drink ist kompatibel zu Object: Beer beer = new Beer ("Jever"); Drink drink = beer; Object object = drink; Man könnte daher auf die nahe liegende Idee kommen, dass auch Bottle<Beer> kompatibel zu Bottle<Drink> und Bottle<Drink> kompatibel zu Bottle<Object> ist: Bottle<Beer> beerbottle = new Bottle<Beer> (); Bottle<Drink> drinkbottle = beerbottle; // illegal Bottle<Object> objectbottle = drinkbottle; // illegal Die beiden letzten Zeilen werden aber vom Compiler als fehlerhaft zurückgewiesen. Die Typen sind also nicht kompatibel obwohl die Typen der Parameter der Bottle-Typen kompatibel sind! Der Grund hierfür ist leicht einzusehen. Angenommen, es existiert eine Bierflasche: Bottle<Beer> beerbottle = new Bottle<Beer> (); Angenommen dann, folgende Zuweisung sei möglich (sie ist nicht möglich): Bottle<Drink> drinkbottle = beerbottle; // illegal, but let's assume... Dann würde die Referenzvariable drinkbottle auf ein Objekt des Typs Bottle<Beer> zeigen. Die Variable ist aber vom Typ Bottle<Drink>. Und der Typ einer Referenzvariablen bestimmt, was man mit einer Referenz tun kann. Die fill-methode von Bottle<Drink> begnügt sich mit einem Parameter, der kompatibel zu Drink ist. Über die Variable drinkbottle könnte man die fill-methode wie folgt aufrufen: drinkbottle.fill (new Whitewine ("Riesling"));

9 3.2 Ein generischer Flaschentyp 29 Mit dem Ergebnis, dass die Bierflasche nun plötzlich Wein beinhaltet. Eben deshalb darf es nicht zulässig sein, eine Referenz vom Typ Bottle<Beer> an eine vom Typ Bottle<Drink> zuzuweisen. Man kann zwar Bier als Getränk betrachten, nicht aber eine Bierflasche als Getränkeflasche. Anders gesagt: Generizität definiert keine Vererbung. Generizität und Vererbung sind orthogonal zueinander. Generizität hat nichts mit Generalisierung/Spezialisierung zu tun. Das Generics-Konzept unterstützt typsicheres Programmieren. Es führt dazu, dass die Verwendung von instanceof und die Verwendung des Downcasts bis auf wenige Ausnahmefälle der Vergangenheit angehören sollten. Rohe Typen Aufgrund der obigen Bottle-Definition ist es auch möglich, einfach nur Bottle als Typ zu verwenden (ohne <...>): Bottle bottle = new Bottle (); Ein solcher Typ wird als Raw-Type bezeichnet. In die durch bottle referenzierte Flasche kann alles Mögliche gefüllt werden. Die fill-methode dieses Typs besitzt einen formalen Parameter vom Typ Object; die empty-methode liefert eine Object-Referenz zurück: bottle.fill ("Hello World"); Object object = bottle.empty (); String s = (String) object; Der Typ Bottle scheint auf den ersten Blick identisch zu sein mit Bottle<Object>. Beim genaueren Hinsehen aber existieren wesentliche Unterschiede: Man kann einer Bottle-Referenz z.b. eine Bottle<Beer>-Referenz zuweisen: Bottle bottle = new Bottle<Beer> (); bottle.fill (new WhiteWine ("Riesling")); WhiteWine whitewine = (WhiteWine) bottle.empty (); System.out.println (whitewine); Wäre bottle nicht vom rohen Typ Bottle, sondern vom Typ Bottle<Object>, so wäre diese Zuweisung nicht möglich. Man erkennt am obigen Beispiel aber auch, dass man mit rohen Typen einigen Unsinn programmieren kann! Man befindet sich nur dann auf der typsicheren Seite, wenn man die Vermischung von rohen Typen und parametrisierten Typen vermeidet.

10 30 Eingeschränkte Typ-Parameter Die parametrisierte Klasse Bottle konnte bislang auch genutzt werden, um aus ihr den Typ Bottle<Object> zu generieren. Das T in der Bottle-Definition konnte durch jeden konkreten Typ ersetzt werden. Gesetzt aber den Fall, man möchte eine Klasse für Getränkeflaschen definieren dann muss es für die aktuellen Typen, durch welche der formale Typ-Parameter der Klasse (T) ersetzt werden kann, die Einschränkung geben, dass er nur durch Drink-kompatible Typen»ersetzt«werden kann. Diese Einschränkung kann wie folgt formuliert werden: class Bottle<T extends Drink> {... Hier wird der Typ T eingeschränkt: Alle aktuellen Typen, durch die T ersetzt werden kann, müssen kompatibel zu Drink sein. Aus dem neuen Bottle-Typ können daher nur noch folgende Typen generiert werden: Bottle<Drink> Bottle<Beer> Bottle<Wine> Bottle<WhiteWine> Bottle<RedWine> Die folgenden Typen z.b. sind unzulässig (sofern Petrol nicht von Drink abgeleitet ist): Bottle<Petrol> Bottle<Object> Man kann sich also vorstellen, dass die»alte«definition der Bottle-Klasse: class Bottle<T> {... nur eine abkürzende Schreibweise für die folgende ausführliche Form ist: class Bottle<T extends Object> {... Genauso wie class C {... bekanntlich nur eine abkürzende Form für class C extends Object {... ist.

11 3.2 Ein generischer Flaschentyp 31 Arrays mit parametrisierten Typen? Angenommen, man möchte einen Kasten bauen, der sechs Bierflaschen enthalten kann. Hier die nahe liegende Formulierung: class BeerBottleBox { private Bottle<Beer> [] bottles = new Bottle<Beer> [6];... Leider meldet der Compiler einen Fehler:»Arrays of generic type are not allowed«. Man kann das Problem zunächst derart lösen, dass man einen Array mit Object-Referenzen erzeugt und die Klasse dann mit typsicheren Methoden ausstattet: class BeerBottleBox { private Object [] bottles = new Object [6]; private int count = 0; public boolean isfull () { return this.bottles.length == this.count; public int getbottlecount () { return this.count; public int getcapacity () { return this.bottles.length; public void add (Bottle<Beer> bottle) { if (this.isfull ()) throw new IllegalStateException (); this.bottles [this.count] = bottle; this.count++; public Bottle<Beer> getbottle (int index) { return (Bottle<Beer>) this.bottles [index]; Die add-methode verlangt eine Bierflasche und die getbottle-methode liefert eben eine solche zurück. Nach demselben Schema könnte man einen Weißweinflaschenkasten bauen. (Genaueres zum Thema Arrays und generische Typen findet sich im Kapitel 4»Generics systematisch betrachtet«.)

12 32 Container mit Typ-parametrisiertem Inhalt Natürlich wäre es wünschenswert, eine einzige Klasse BottleBox schreiben zu können, deren Objekte entweder Bierflaschen, Rotweinflaschen oder Weißweinflaschen aufnehmen können. Hier eine mögliche Lösung: class BottleBox<T extends Drink> { private Object [] bottles = new Object [6]; private int count = 0; public boolean isfull () {... public int getbottlecount () {... public int getcapacity () {... public void add (Bottle<T> bottle) { if (this.isfull ()) throw new IllegalStateException (); this.bottles [this.count] = bottle; this.count++; public Bottle<T> getbottle (int index) { return (Bottle<T>) this.bottles [index]; Auf Grundlage dieser Klasse könnte man dann einen Bierflaschenkasten füllen und leeren: BottleBox<Beer> beerbottlebox = new BottleBox<Beer> (); for (int i = 0; i < beerbottlebox.getcapacity (); i++) { Bottle<Beer> beerbottle = new Bottle<Beer> (); beerbottle.fill (new Beer ("Jever")); beerbottlebox.add (beerbottle); for (int i = 0; i < beerbottlebox.getbottlecount (); i++) { Bottle<Beer> beerbottle = beerbottlebox.getbottle (i); Beer beer = beerbottle.empty (); System.out.println (beer); Vom Compiler wird garantiert, dass in die beerbottlebox nur Bierflaschen eingefügt werden können.

13 3.3 Vergleichbarkeit von Flaschen Vergleichbarkeit von Flaschen Oben wurde gesagt, dass zwar Beer und Wine kompatibel sind zu Drink, nicht aber Bottle<Beer> und Bottle<Wine> zu Bottle<Drink>. Die folgende Zeile würde also der Compiler als fehlerhaft zurückweisen: Bottle<Drink> drinkbottle = new Bottle<Beer> (); // illegal Die Begründung für das Verhalten des Compilers wurde oben dargestellt. Angenommen, man möchte nun einen Kasten bauen, der alle möglichen Getränkeflaschen beinhalten kann. Dies scheint auf den ersten Blick nicht möglich zu sein. (Es sei denn, man geht auf den rohen Typ zurück mit der damit verbundenen Typunsicherheit.) Um dieses Problem und damit verwandte Probleme trotzdem typsicher lösen zu können, hat Java eine so genannte Wildcard eingeführt. Angenommen, man hat eine Bierflasche erzeugt und gefüllt: Bottle<Beer> beerbottle = new Bottle<Beer> (); beerbottle.fill (new Beer ("Veltins")); Man kann nun folgende Referenzvariable definieren: Bottle<? extends Drink> drinkbottle; Das? wird als Wildcard bezeichnet. Es steht für irgendeinen Typ (der in der obigen Definition aber eingeschränkt ist auf Drink er muss also Drink-kompatibel sein).? extends Drink könnte man also übersetzen mit»any«drink. Dann kann dieser Variablen auf eine typsichere Art die Bierflasche (oder auch eine Weißwein- oder Rotweinflasche) zugewiesen werden: drinkbottle = beerbottle; Man kann also den Typ Bottle<? extends Drink> als Supertyp der Klassen Bottle<Beer>, Bottle<WhiteWine> etc. betrachten. Interessant ist nun, was man mit drinkbottle tun kann. Betrachten wir zunächst, was man mit beerbottle tun könnte (beerbottle ist vom Typ Bottle<Beer>): beerbottle.fill (new Beer ("Jever")); Beer beer = beerbottle.empty (); Über beerbottle kann man die Bierflasche also sowohl leeren als auch füllen (was selbstverständlich ist). Der Versuch, nun aber über drinkbottle die Bierflasche zu füllen, würde vom Compiler als fehlerhaft zurückgewiesen: drinkbottle.fill (new Beer ("Jever"));// illegal Mit anderen Worten: Es gibt keinen einzigen Typ, der kompatibel wäre zu <? extends Drink> nicht einmal Drink selbst (und auch nicht Object). Die fill-

14 34 Methode des Typs Bottle<? extends Drink> verlangt aber eben genau einen Parameter eines solchen Typs. Und daraus folgt: die fill-methode kann über eine Bottle<? extends Drink>-Referenz niemals aufgerufen werden! (Es sei denn, man übergibt ihr null.) Und das ist auch richtig so. Anders verhält es sich mit der empty-methode. Aufgerufen über eine Referenz vom Typ <? extends Drink> liefert sie eben auch <? extends Drink> zurück also eine Referenz, welche auf jeden Fall auf ein Drink-kompatibles Objekt zeigen wird. Die folgende Zeile ist somit völlig korrekt: Drink drink = drinkbottle.empty (); Also: Über die drinkbottle-referenz kann man zwar die Flasche nicht füllen, aber durchaus leeren. Dann ist auch klar, wie man eine Klasse für Kästen definieren kann, welche beliebige Getränkeflaschen aufnehmen können: class BottleBox { private Object [] bottles = new Object [6]; private int count = 0; public boolean isfull () {... public int getcapacity () {... public int getbottlecount () {... public void add (Bottle<? extends Drink> bottle) { if (this.isfull ()) throw new IllegalStateException (); this.bottles [this.count] = bottle; this.count++; public Bottle<? extends Drink> getbottle (int index) { return (Bottle<? extends Drink>) this.bottles [index]; Es handelt sich hier um eine»gewöhnliche«klasse, die nicht Typ-parametrisiert ist. Ihre add-methode verlangt einen Parameter, dessen Typ kompatibel zu Bottle<? extends Drink> ist also z.b. eine Bierflasche oder eine Rotweinflasche oder eine Weißweinflasche. Die getbottle-methode liefert eine dementsprechende Referenz zurück. Folgende Operationen wären damit möglich: BottleBox box = new BottleBox (); Bottle<Beer> beerbottle = new Bottle<Beer> (); beerbottle.fill (new Beer ("Veltins")); box.add (beerbottle); Bottle<WhiteWine> whitewinebottle = new Bottle<WhiteWine> (); whitewinebottle.fill (new WhiteWine ("Riesling")); box.add (whitewinebottle);

15 3.3 Vergleichbarkeit von Flaschen 35 for (int i = 0; i < box.getbottlecount (); i++) { Bottle<? extends Drink> bottle = box.getbottle (i); Drink drink = bottle.empty (); System.out.println (drink); Man beachte hier wieder, dass die fill-operation nur über die Variablen beer- Bottle und whitewinebottle aufgerufen werden kann. Über die drink-referenz (in der Schleife) können die Flaschen nur geleert werden. Noch einmal: Container mit Typ-parametrisiertem Inhalt Weiter oben wurde eine Klasse für Kästen definiert, welche jeweils nur Flaschen eines bestimmten Typs aufnehmen konnten: class BottleBox<T extends Drink> {... public void add (Bottle<T> bottle) {... public Bottle<T> getbottle (int index) {... Auf Grundlage dieser Definition konnte man z.b. einen Bierflaschenkasten erzeugen: BottleBox<Beer> beerbox = new BottleBox<Beer> (); Diese BottleBox-Klasse war völlig korrekt sie hat allerdings eine kleine semantische Ungereimtheit. Sie ist parametrisiert mit einem Typ T, welcher kompatibel sein muss mit Drink. Aber es soll doch kein Kasten für Getränke gebaut werden, sondern ein Kasten für Getränkeflaschen. Das sollte auch in der Typ-Parametrisierung klarer ausgedrückt werden können. Mit Wildcards kann dieses Problem angemessener gelöst werden: class BottleBox <T extends Bottle <? extends Drink>> { private Object [] bottles = new Object [6]; private int count = 0; public boolean isfull () {... public int getcapacity () {... public int getbottlecount () {... public void add (T bottle) { if (this.isfull ()) throw new IllegalStateException (); this.bottles [this.count] = bottle; this.count++; public T getbottle (int index) { return (T) this.bottles [index];

16 36 BottleBox ist hier wieder eine Typ-parametrisierte Klasse. Der Typ-Parameter muss kompatibel sein zu Bottle<? extends Drink>. Also könnte z.b. ein Bierkasten erzeugt werden: BottleBox<Bottle<Beer>> box = new BottleBox<Bottle<Beer>> (); Dieser Kasten kann nur Bierflaschen aufnehmen: Bottle<Beer> bottlebeer = new Bottle<Beer> (); bottlebeer.fill (new Beer ("Veltins")); box.add (bottlebeer); Und in den folgenden Zeilen werden alle Bierflaschen dieses Kastens geleert: for (int i = 0; i < box.getbottlecount (); i++) { Bottle<Beer> b = box.getbottle (i); Beer beer = b.empty (); System.out.println (beer); 3.4 Umfüllen von Flaschen Angenommen, es existiere das (zugegebenermaßen fiktive) Problem, den Inhalt einer Getränkeflasche jeweils in eine andere Flasche umzufüllen. Diese Aufgabe könnte ein BottleTransfuser übernehmen. Natürlich muss sichergestellt sein, dass der Inhalt einer Bierflasche nur in eine andere Bierflasche und der Inhalt einer Rotweinflasche nur in eine andere Rotweinflasche umgefüllt werden kann. Man könnte folgende Typ-parametrisierte Klasse schreiben: class BottleTransfuser <T extends Bottle<? extends Drink>> { public void transfuse (T frombottle, T tobottle) { Drink drink = frombottle.empty (); tobottle.fill (drink); Leider wird diese Klasse vom Compiler nicht übersetzt. (Warum nicht? Leeren geht, füllen nicht!) Also könnte man sich folgender Lösung bedienen: class BottleTransfuser <T extends Drink> { public void transfuse (Bottle<T> frombottle, Bottle<T> tobottle) { T drink = frombottle.empty (); tobottle.fill (drink);

17 3.4 Umfüllen von Flaschen 37 Man könnte dann folgendes Programmfragment schreiben: BottleTransfuser<Beer> beertransfuser = new BottleTransfuser<Beer> (); Bottle<Beer> b1 = new Bottle<Beer> (); b1.fill (new Beer ("Jever")); Bottle<Beer> b2 = new Bottle<Beer> (); transfuser.beertransfuser (b1, b2); Der beertansfuser macht seine Sache typsicher aber genau in dieser Typsicherheit liegt auch seine Beschränktheit: Er kann nur Bierflaschen umfüllen. Um Rotweinflaschen umzufüllen, bräuchte man also einen zweiten Umfüller, einen, der ausschließlich für Rotweine zuständig ist: einen BottleTransfuser<RedWine>. Die Typsicherheit, die hier verlangt werden sollte, besteht aber nur darin, dass ein Umfüller während seiner Tätigkeit des Umfüllens Bier nicht in Weinflaschen füllt oder umgekehrt.»während der Tätigkeit des Umfüllens«also während der Ausführung der transfuse-methode. Zur Lösung dieses Problems kann eine generische Methode verwendet werden: class BottleTransfuser { public <T extends Drink> void transfuse ( Bottle<T> frombottle, Bottle<T> tobottle) { T drink = frombottle.empty (); tobottle.fill (drink); Man beachte den Typ-Parameter vor dem Typ der Methode (vor void). Genau dieser wird in der Parameterliste der Methode verwendet. Nur die Methode transfuse ist Typ-parametrisiert, nicht aber die Klasse. Die Methodendefinition stellt sicher, dass beide ihr übergebenen Parameter vom selben Typ sind nämlich vom Typ Bottle<T>. Ein BottleTransfuser kann dann sowohl Bier- in Bierflaschen als auch Weißwein- in Weißweinflaschen umfüllen: BottleTransfuser transfuser = new BottleTransfuser (); Bottle<Beer> b1 = new Bottle<Beer> (); b1.fill (new Beer ("Jever")); Bottle<Beer> b2 = new Bottle<Beer> (); transfuser.transfuse (b1, b2); Bottle<WhiteWine> b3 = new Bottle< WhiteWine > (); b3.fill (new WhiteWine ("Riesling")); Bottle< WhiteWine > b4 = new Bottle< WhiteWine > (); transfuser.transfuse (b3, b4); Fogende Zeile würde der Compiler nicht übersetzen: transfuser.transfuse (b1, b4); // illegal (Man darf kein Bier in eine Weinflasche füllen dürfen.)

18 38 Natürlich hätte die Methode transfuse auch static sein können: class BottleTransfuser { public static <T extends Drink> void transfuse ( Bottle<T> frombottle, Bottle<T> tobottle) { T drink = frombottle.empty (); tobottle.fill (drink); Dann hätte man die Flaschen wie folgt umfüllen können: BottleTransfuser.transfuse (b1, b2); BottleTransfuser.transfuse (b3, b4);

Typsystem Vererbung Sonstiges. Java 5 Typsystem. Generische Klassen und ihre Auswirkungen auf das Typsystem. Sebastian Buchwald. Universität Karlsruhe

Typsystem Vererbung Sonstiges. Java 5 Typsystem. Generische Klassen und ihre Auswirkungen auf das Typsystem. Sebastian Buchwald. Universität Karlsruhe Typsystem Generische Klassen und ihre Auswirkungen auf das Typsystem Universität Karlsruhe 12. Juli 2007 Gliederung Typsystem 1 Typsystem 2 3 Typinferenz Wildcard Capture Gliederung Typsystem 1 Typsystem

Mehr

Faulheit professionell: Fertige Datenbehälter. Das Java-Collections-Framework Typsicherheit Generische Klassen

Faulheit professionell: Fertige Datenbehälter. Das Java-Collections-Framework Typsicherheit Generische Klassen Faulheit professionell: Fertige Datenbehälter Das Java-Collections-Framework Typsicherheit Generische Klassen Das Java Collections Framework Grundlegende Interfaces Das Interface List Das Interface List

Mehr

1 Einleitung Generizität Syntax... 2

1 Einleitung Generizität Syntax... 2 Inhaltsverzeichnis Inhaltsverzeichnis 1 Einleitung 1 1.1 Generizität................................ 1 1.2 Syntax.................................. 2 2 Realisierung 2 2.1 Compilierung generischer Klassen...................

Mehr

Programmieren 2 16 Java Collections und Generizität

Programmieren 2 16 Java Collections und Generizität Programmieren 2 16 Java Collections und Generizität Bachelor Medieninformatik Wintersemester 2015 Dipl.-Inform. Ilse Schmiedecke schmiedecke@beuth-hochschule.de 1 Faulheit professionell: Fertige Datenbehälter

Mehr

Abschnitt 10: Typisierte Klassen

Abschnitt 10: Typisierte Klassen Abschnitt 10: Typisierte Klassen 10. Typisierte Klassen 10.1 Einführung: Grenzen der Typ-Polymorphie durch Vererbung 10.2 Grundlagen 10.3 Vererbung bei typisierten Klassen 10.4 Wildcards, obere und untere

Mehr

4. Vererbung Die Klasse Object. Die Klasse Object

4. Vererbung Die Klasse Object. Die Klasse Object 4. Vererbung Die Klasse Object Die Klasse Object Alle Klassen ohne explizit deklarierte Superklasse haben die Klasse Object als Superklasse. Object gehört zum Paket java.lang. Object verfügt über einige

Mehr

Die abstrakte Klasse Expression:

Die abstrakte Klasse Expression: Die abstrakte Klasse Expression: Expression abstract evaluate() Add Neg Const 501 Die abstrakte Klasse Expression: Expression abstract evaluate() Add Neg Const Leider (zum Glück?) lässt sich nicht die

Mehr

Institut für Programmierung und Reaktive Systeme. Java 7. Markus Reschke

Institut für Programmierung und Reaktive Systeme. Java 7. Markus Reschke Institut für Programmierung und Reaktive Systeme Java 7 Markus Reschke 14.10.2014 Vererbung in Java Vererbung ermöglicht es, Klassen zu spezialisieren Wiederverwendung vorhandener Klassen Kindsklasse erhält

Mehr

Generisches Programmieren. Generisches Programmieren

Generisches Programmieren. Generisches Programmieren Generisches Programmieren Generisches Programmieren 24.11.11 Uli Dormann 1 Inhaltsverzeichnis Motivation Ansatz Sprachen mit generischer Programmierung Generische Klassen Namenskonvention Prüfung Typsicherheit

Mehr

55 Ring-Queue. size. push. clear. get. Reinhard Schiedermeier / Klaus Köhler, Das Java-Praktikum, dpunkt.verlag, ISBN

55 Ring-Queue. size. push. clear. get. Reinhard Schiedermeier / Klaus Köhler, Das Java-Praktikum, dpunkt.verlag, ISBN D3kjd3Di38lk323nnm 394 55 Ring-Queue In dieser Aufgabe wird eine generische Containerklasse definiert. Ihre Kapazität wird beim Erzeugen festgelegt, im Gegensatz zu den Klassen des Collection- Frameworks.

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java 1 / 22 Einstieg in die Informatik mit Java Generics Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 22 1 Überblick Generics 2 Generische Klassen 3 Generische Methoden 4

Mehr

Universität Karlsruhe (TH)

Universität Karlsruhe (TH) Universität Karlsruhe (TH) Lehrstuhl für Programmierparadigmen Fortgeschr. Objektorientierung SS 2009 http://pp.info.uni-karlsruhe.de/ Dozent: Prof. Dr.-Ing. G. Snelting snelting@ipd.info.uni-karlsruhe.de

Mehr

12 Abstrakte Klassen, finale Klassen und Interfaces

12 Abstrakte Klassen, finale Klassen und Interfaces 12 Abstrakte Klassen, finale Klassen und Interfaces Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält,

Mehr

Programmierung Nachklausurtutorium

Programmierung Nachklausurtutorium Programmierung Nachklausurtutorium Laryssa Horn, Tim Engelhardt 20 März 2018 Klassen Wofür wir Klassen brauchen: Definieren ein Bauplan eines Objektes Bauplan enthält Attribute und Methoden Klasse Beispiel

Mehr

Vorkurs Informatik WiSe 15/16

Vorkurs Informatik WiSe 15/16 Java 7 Dr. Werner Struckmann / Stephan Mielke, Jakob Garbe, 21.10.2015 Technische Universität Braunschweig, IPS Überblick OO in Java Vererbung Abstrakte Klassen und Interfaces 21.10.2015 Dr. Werner Struckmann

Mehr

Durch die Möglichkeit, Ein- und Ausgaben auf der Konsole durchzuführen, kann man auch systematisch das Verhalten von Klassen analysieren.

Durch die Möglichkeit, Ein- und Ausgaben auf der Konsole durchzuführen, kann man auch systematisch das Verhalten von Klassen analysieren. Durch die Möglichkeit, Ein- und Ausgaben auf der Konsole durchzuführen, kann man auch systematisch das Verhalten von Klassen analysieren. 267 Das hier skizzierte Problem basiert auf der strategischen Entscheidung

Mehr

Programmierkurs Java

Programmierkurs Java Programmierkurs Java Java Generics und Java API (1/2) Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck https://www.itm.uni-luebeck.de/people/fischer Datenstrukturen In vielen Sprachen

Mehr

Probleme ohne generische Typen

Probleme ohne generische Typen Generics seit Java1.5 SSJ Kapitel 15 Probleme ohne generische Typen Klassen, die mit Objekten verschiedenen Typs arbeiten können class List { Object[ ] data = ; void add(object x) { Object remove() { Probleme

Mehr

Informatik II Übung 6

Informatik II Übung 6 Informatik II Übung 6 Gruppe 2 Carina Fuss cfuss@student.ethz.ch 11.4.2018 Carina Fuss 11.4.2018 1 Übung 6 Nachbesprechung Übung 5 Objektorientierung Vererbung, Polymorphie, abstrakte Klassen, Interfaces,

Mehr

Überblick. Peer Kröger (LMU München) Einführung in die Programmierung WS 16/ / 861

Überblick. Peer Kröger (LMU München) Einführung in die Programmierung WS 16/ / 861 Überblick 9. 9.1 Vererbung, abstrakte Klassen, Polymorphismus 9.2 Interfaces 9.3 Ausnahmen 9.4 Peer Kröger (LMU München) Einführung in die Programmierung WS 16/17 790 / 861 Grundlegendes zu Typsystemen

Mehr

Probeklausur: Programmierung WS04/05

Probeklausur: Programmierung WS04/05 Probeklausur: Programmierung WS04/05 Name: Hinweise zur Bearbeitung Nimm Dir für diese Klausur ausreichend Zeit, und sorge dafür, dass Du nicht gestört wirst. Die Klausur ist für 90 Minuten angesetzt,

Mehr

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass: OOP (Java), 22. Aufzählungstypen 1/20 Objektorientierte Programmierung Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester

Mehr

Die Klasse java.lang.object. Thorsten Treffer

Die Klasse java.lang.object. Thorsten Treffer Die Klasse java.lang.object Thorsten Treffer 6. Dezember 2003 1 java.lang.object Die Klassenhierarchie von Java kann als Baum aufgezeichnet werden, dessen Wurzel die Klasse Object ist. Mit anderen Worten:

Mehr

Realisierungsmöglichkeiten für parametrische Polymorphie

Realisierungsmöglichkeiten für parametrische Polymorphie 4. Parametrisierbare Klassen Realisierung von Generics Realisierungsmöglichkeiten für parametrische Polymorphie heterogen Für jeden konkreten Typ wird individueller Code erzeugt (type expansion). Diesen

Mehr

Kapitel 8. Generische Klassen

Kapitel 8. Generische Klassen Kapitel 8 Generische Klassen Ziel: Zusammensetzen von Software-Bausteinen Oft probiert, nie erreicht! sprachliche Mittel fehlten In C++, ADA, Eiffel, Java: Klassen, die mit anderen Klassen parametrisiert

Mehr

Programmieren in Java

Programmieren in Java Programmieren in Java Vorlesung 05: Generics Prof. Dr. Peter Thiemann Albert-Ludwigs-Universität Freiburg, Germany SS 2015 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 1 / 19 Inhalt Generics

Mehr

Einführung in die Programmierung

Einführung in die Programmierung Einführung in die Programmierung Teil 10: Typsicherheit durch generische Typen Prof. Dr. Peer Kröger, Florian Richter, Michael Fromm Wintersemester 2018/2019 Übersicht 1. Grundlagen 2. Typvariablen 3.

Mehr

Algorithmen und Programmierung II

Algorithmen und Programmierung II Algorithmen und Programmierung II Vererbung Prof. Dr. Margarita Esponda SS 2012 1 Imperative Grundbestandteile Parameterübergabe String-Klasse Array-Klasse Konzepte objektorientierter Programmierung Vererbung

Mehr

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen Kapitel 9 Programmierkurs Birgit Engels Anna Schulze Zentrum für Angewandte Informatik Köln Objektorientierte Programmierung Attribute von Klassen, Methoden und Variablen Interfaces WS 07/08 1/ 18 2/ 18

Mehr

Kapitel 8. Generische Klassen

Kapitel 8. Generische Klassen Kapitel 8 Generische Klassen Ziel: Zusammensetzen von Software-Bausteinen Oft probiert, nie erreicht! sprachliche Mittel fehlten In C++, ADA, Eiffel, Java: Klassen, die mit anderen Klassen parametrisiert

Mehr

Einfache Liste: Ein Stapel (Stack) Ansatz. Schaubild. Vorlesung 1. Handout S. 2. Die einfachste Form einer Liste ist ein Stapel (stack).

Einfache Liste: Ein Stapel (Stack) Ansatz. Schaubild. Vorlesung 1. Handout S. 2. Die einfachste Form einer Liste ist ein Stapel (stack). Programmieren I Martin Schultheiß Hochschule Darmstadt Sommersemester 2011 1 / 64 2 / 64 Motivation Hauptteil dieser Vorlesung sind die so genannten. Zur Motivation (und als Vorbereitung der Datencontainer-Klassen

Mehr

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz Kapitel 13 Abstrakte Methoden und Interfaces 13. Abstrakte Klassen und Interfaces 1. Abstrakte Klassen 2. Interfaces und Mehrfachvererbung Folie 12.2 Abstrakte Methoden und Klassen Manchmal macht es überhaupt

Mehr

Wiederholung. Klassenhierarchie:

Wiederholung. Klassenhierarchie: Wiederholung Klassenhierarchie: class Unter extends Ober {... Die Unterklasse Unter erweitert die Funktionalität ihrer Oberklasse Ober. Objekte der Klasse Unter können anstelle von Objekten der Klasse

Mehr

Informatik II Übung 06. Benjamin Hepp 5 April 2017

Informatik II Übung 06. Benjamin Hepp 5 April 2017 Informatik II Übung 06 Benjamin Hepp benjamin.hepp@inf.ethz.ch 5 April 2017 Nachbesprechung U5 5 April 2017 Informatik II - Übung 01 2 Nachbesprechung U5 1. Einfach verkettete Listen Keine Probleme 2.

Mehr

Java I Vorlesung 6 Referenz-Datentypen

Java I Vorlesung 6 Referenz-Datentypen Java I Vorlesung 6 Referenz-Datentypen 7.6.2004 Referenzen this, super und null Typkonvertierung von Referenztypen Finale Methoden und Klassen Datentypen in Java In Java gibt es zwei Arten von Datentypen:

Mehr

Polymorphie. 15. Java Objektorientierung II

Polymorphie. 15. Java Objektorientierung II 432 Polymorphie 15. Java Objektorientierung II Objektorientierung: Verschiedene Aspekte 433 Daten Typhierarchie Objekte Code Vererbung Unter- und Oberklassen Methoden überschreiben Unterklassen zuweisen

Mehr

Polymorphie. 15. Java Objektorientierung II

Polymorphie. 15. Java Objektorientierung II 446 Polymorphie 15. Java Objektorientierung II Objektorientierung: Verschiedene Aspekte 447 Daten Typhierarchie Objekte Code Vererbung Unter- und Oberklassen Methoden überschreiben Unterklassen zuweisen

Mehr

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung Javakurs FSS 2012 Lehrstuhl Stuckenschmidt Tag 3 - Objektorientierung Warum Objektorientierung Daten und Funktionen möglichst eng koppeln und nach außen kapseln Komplexität der Software besser modellieren

Mehr

Programmieren in Java

Programmieren in Java Generische Datentypen 2 Wiederholung: Fehlerbehandlung durch Exceptions Die Ausführung einer Methode kann jederzeit durch das Werfen einer Exception-Instanz beendet werden Methoden, die durch eine Exception

Mehr

Interface. So werden Interfaces gemacht

Interface. So werden Interfaces gemacht Design Ein Interface (=Schnittstelle / Definition) beschreibt, welche Funktionalität eine Implementation nach Aussen anzubieten hat. Die dahinter liegende Algorithmik wird aber der Implementation überlassen.

Mehr

Überschreiben von Methoden

Überschreiben von Methoden Vergleich der DoME Realisierungen: Methode ausgeben Version 1 (ohne Vererbung): Anzeigen aller Informationen CD: A Swingin Affair (64 Min)* Frank Sinatra Titelanzahl: 16 Mein Lieblingsalbum von Sinatra

Mehr

Java Einführung Vererbung und Polymorphie. Kapitel 13

Java Einführung Vererbung und Polymorphie. Kapitel 13 Java Einführung Vererbung und Polymorphie Kapitel 13 Inhalt Klassifikation (UML) Implementierung von Vererbungshierarchien Überschreiben von Methoden Polymorphismus: Up-Casting und Dynamisches Binden Schlüsselwort

Mehr

II.4.4 Exceptions - 1 -

II.4.4 Exceptions - 1 - 1. Unterklassen und Vererbung 2. Abstrakte Klassen und Interfaces 3. Modularität und Pakete 4. Ausnahmen (Exceptions) 5. Generische Datentypen 6. Collections II.4.4 Exceptions - 1 - Ausnahmen (Exceptions)

Mehr

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Referenzen. Referenzen

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Referenzen. Referenzen 5 Objektorientierte Programmierung in Java Prof. Dr. Ing. André Stuhlsatz Referenzen Beispiel an der einfachen Klasse Walze: public class Walze { int id; public Walze(int id) { this.id = id; Verwenden

Mehr

Felder - Arrays. Typ feldname[] = new Typ[<ganze Zahl >]; Beispiel: double vektor[] = new double[5]; auch eine Initialisierung ist möglich.

Felder - Arrays. Typ feldname[] = new Typ[<ganze Zahl >]; Beispiel: double vektor[] = new double[5]; auch eine Initialisierung ist möglich. Felder Felder - Arrays Variable gleichen Types können in Feldern (array) zusammengefasst werden. Typ[] feldname; oder Typ feldname[]; dabei kann unter Benutzung des new-operators gleich die Dimension zugewiesen

Mehr

II.4.4 Exceptions - 1 -

II.4.4 Exceptions - 1 - n 1. Unterklassen und Vererbung n 2. Abstrakte Klassen und Interfaces n 3. Modularität und Pakete n 4. Ausnahmen (Exceptions) n 5. Generische Datentypen n 6. Collections II.4.4 Exceptions - 1 - Ausnahmen

Mehr

JAVA 5 Generics. Proseminar Programmiersprachen Thema Java 5 Generics 1

JAVA 5 Generics. Proseminar Programmiersprachen Thema Java 5 Generics 1 JAVA 5 Generics Thema Java 5 Generics 1 Inhalt 1. Die Programmiersprache Java 2. Simple Generics 3. Das Beispielprogramm 4. Tieferer Einstieg in Generics 5. Arrays 6. Kritische Betrachtung von Generics

Mehr

Grundzüge der Programmierung. Wiederverwendung VERERBUNG

Grundzüge der Programmierung. Wiederverwendung VERERBUNG Grundzüge der Programmierung Wiederverwendung VERERBUNG Inhalt dieser Einheit Syntax: Vererbung in Java Superklassen - Subklassen Konstruktorenaufruf in Subklassen super, abstract und final 2 Code-Reuse

Mehr

Wie kann man es verhindern das Rad immer wieder erneut erfinden zu müssen?

Wie kann man es verhindern das Rad immer wieder erneut erfinden zu müssen? Generic Programming without Generics from JAVA5 Motivation Wie kann man es verhindern das Rad immer wieder erneut erfinden zu müssen? Ein Bespiel: sie haben bereits eine Klasse zur Multiplikation von Matrizen

Mehr

Beuth Hochschule Parameter-Übergabe-Mechanismen WS17/18, S. 1

Beuth Hochschule Parameter-Übergabe-Mechanismen WS17/18, S. 1 Beuth Hochschule Parameter-Übergabe-Mechanismen WS17/18, S. 1 Parameter-Übergabe-Mechanismen in Java und in anderen Sprachen. 1. Methoden vereinbaren mit Parametern Wenn man (z.b. in Java) eine Methode

Mehr

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik Programmieren II Innere Klassen Heusch 10, 13.10 Ratz 5.2.1, 9.8 KIT Die Forschungsuniversität in der Helmholtz-Gemeinschaft www.kit.edu Innere Klassen Bisher kennen wir nur Klassen, die entweder zusammen

Mehr

Algorithmen und Datenstrukturen 07

Algorithmen und Datenstrukturen 07 (7. Juni 2012) 1 Besprechung Blatt 6 Fragen 2 Referenzen Referenzsemantik 3 Vererbung Allgemein abstract Interfaces Vererbung in UML 4 Vorbereitung Blatt 7 Anmerkungen Fragen Fragen zu Blatt 6? Referenzsemantik

Mehr

Programmiermethodik 2. Klausur Lösung

Programmiermethodik 2. Klausur Lösung Programmiermethodik 2. Klausur Lösung 2. 10. 2013 Name Matrikelnummer Aufgabe mögliche Punkte erreichte Punkte 1 20 2 18 3 42 4 20 5 20 Gesamt 120 1 Seite 2 von 12 Aufgabe 1) Objekt-Orientierung und Vererbung

Mehr

Institut für Programmierung und Reaktive Systeme 17. Juli Programmieren II. Übungsklausur

Institut für Programmierung und Reaktive Systeme 17. Juli Programmieren II. Übungsklausur Technische Universität Braunschweig Dr. Werner Struckmann Institut für Programmierung und Reaktive Systeme 17. Juli 2015 Hinweise: Klausurtermine: Programmieren II Übungsklausur Programmieren I: 7. September

Mehr

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden Kapitel 8 Programmierkurs Birgit Engels Anna Schulze Zentrum für Angewandte Informatik Köln Objektorientierte Programmierung Methoden Überladen von Methoden Der this-zeiger Konstruktoren Vererbung WS 07/08

Mehr

Aufgabenblatt 4. Aufgabe 3. Aufgabe 1. Aufgabe 2. Prof. Dr. Th. Letschert Algorithmen und Datenstrukturen

Aufgabenblatt 4. Aufgabe 3. Aufgabe 1. Aufgabe 2. Prof. Dr. Th. Letschert Algorithmen und Datenstrukturen Prof. Dr. Th. Letschert Algorithmen und Datenstrukturen Aufgabenblatt 4 Aufgabe 1 1. Erläutern Sie in eigenen Worten die Begriffe Datenstruktur, Datentyp und abstrakter Datentyp. Nutzen Sie das Beispiel

Mehr

ADT: Verkettete Listen

ADT: Verkettete Listen ADT: Verkettete Listen Abstrakter typ - Definition public class Bruch{ int zaehler, nenner; public Bruch(int zaehler, int nenner) { this.zaehler = zaehler; this.nenner = nenner; Konstruktor zum Initialisieren

Mehr

Kapitel 5: Iterierbare Container

Kapitel 5: Iterierbare Container Kapitel 5: Iterierbare Container Foreach-Schleife Interface Iterator Interface Iterable Iterator-Schleife und Foreach-Schleife Generische Liste mit Iteratoren Prof. Dr. O. Bittel, HTWG Konstanz Programmiertechnik

Mehr

Bei for-schleifen muss man nur immer bedenken, dass die letzte Anweisung immer erst nach der Ausführung der restlichen Anweisungen der Schleife

Bei for-schleifen muss man nur immer bedenken, dass die letzte Anweisung immer erst nach der Ausführung der restlichen Anweisungen der Schleife 303 Bei for-schleifen muss man nur immer bedenken, dass die letzte Anweisung immer erst nach der Ausführung der restlichen Anweisungen der Schleife durchgeführt wird. 304 305 for-schleifen sind in Aktivitätsdiagrammen

Mehr

Was du ererbt von Deinen Vätern hast, erwirb es, um es zu besitzen. J. W. v. Goethe.

Was du ererbt von Deinen Vätern hast, erwirb es, um es zu besitzen. J. W. v. Goethe. Was du ererbt von Deinen Vätern hast, erwirb es, um es zu besitzen. J. W. v. Goethe http://www.zitate-online.de/autor/goethe-johann-wolfgang-von/ http://www.weimar-lese.de/files_weimar_lese/johann_wolfgang_von_goethe_bearbeitet_von_andreas_werner.jpg

Mehr

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer 144

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer   144 Rechtsbelehrung Dieser Foliensatz ist urheberrechtlich geschützt. Änderungen an den Folien sind untersagt. Ausschließlich eine nicht-kommerzielle Nutzung ist kostenfrei. Andernfalls wird eine Gebühr fällig.

Mehr

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D. TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D. Übung zur Vorlesung Einführung in die Informatik 2 für Ingenieure (MSE) Alexander van Renen (renen@in.tum.de)

Mehr

Programmieren in Java -Eingangstest-

Programmieren in Java -Eingangstest- Programmieren in Java -Eingangstest- Nummer: 1. Studiengang: Informatik B.Sc. Informatik M.Sc. ESE B.Sc. ESE M.Sc. Sonstiges: Fachsemester: Bitte Fragen, die Sie nicht beantworten können unbedingt mit

Mehr

Prüfung Softwareentwicklung II (IB)

Prüfung Softwareentwicklung II (IB) Hochschule für angewandte Wissenschaften München Fakultät für Informatik und Mathematik Studiengruppe IB 2 B, IB 2 C Sommersemester 2013 Prüfung Softwareentwicklung II (IB) Datum : 11.07.2013, 08:30 Uhr

Mehr

1 Abstrakte Klassen, finale Klassen und Interfaces

1 Abstrakte Klassen, finale Klassen und Interfaces 1 Abstrakte Klassen, finale Klassen und Interfaces Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält,

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java 1 / 15 Einstieg in die Informatik mit Java Collections Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 15 1 Überblick Collections 2 Hierarchie von Collections 3 Verwendung

Mehr

Test-Klausuraufgaben Softwaretechnik Fachbereich BW, für WINFO

Test-Klausuraufgaben Softwaretechnik Fachbereich BW, für WINFO Test-Klausuraufgaben Softwaretechnik Fachbereich BW, für WINFO Dipl.-Ing. Klaus Knopper 21.12.2006 Hinweis: Bitte schreiben Sie auf das Deckblatt und auf jede Seite Ihren Namen und Ihre Matrikelnummer,

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen Tafelübung 03 Vererbung, Polymorphie, Sichtbarkeit, Interfaces Clemens Lang T2 11. Mai 2010 14:00 16:00, 00.152 Tafelübung zu AuD 1/26 Klassen und Objekte Klassen und Objekte

Mehr

Neuere Sprachelemente in Java

Neuere Sprachelemente in Java Softwaretechnik 1 Vorlesung Neuere Sprachelemente in Java Prof. Dr. Bernhard Rumpe Technische Universität Braunschweig http://www.sse.cs.tu-bs.de/ Seite 2 Neuerungen seit Java 5.0 Java Spracherweiterungen

Mehr

Vererbung und Polymorphie

Vererbung und Polymorphie Vererbung und Polymorphie Marc Satkowski, Sascha Peukert 29. September 2016 C# Kurs Gliederung 1. Methodenüberladung 2. Vererbung Polymorphie Methoden- & Eigenschaftsüberschreibung Weitere Schlüsselwörter

Mehr

Programmieren I und II

Programmieren I und II Handout zu den Vorlesungen Vorlesung Programmieren I und II Unit 9 Generische Datentypen 1 Prof. Dr. rer. nat. Nane Kratzke Praktische Informatik und betriebliche Informationssysteme Raum: 17-0.10 Tel.:

Mehr

ADT: Verkettete Listen

ADT: Verkettete Listen ADT: Verkettete Listen Abstrakter typ - Definition public class Bruch int zaehler, nenner; public Bruch(int zaehler, int nenner) this.zaehler = zaehler; this.nenner = nenner; Konstruktor zum Initialisieren

Mehr

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download Organisatorisches Folien (u.a.) gibt's auf der Lva-Homepage zum Download Diesen Mi erstes Tutorium (15-17) Ab nächster Woche montags 10-12 (jeweils im Computerraum) 17.10.2017 IT I - VO 3 1 Organisatorisches

Mehr

II.4.1 Unterklassen und Vererbung - 1 -

II.4.1 Unterklassen und Vererbung - 1 - 1. Grundelemente der Programmierung 2. Objekte, Klassen und Methoden 3. Rekursion und dynamische Datenstrukturen 4. Erweiterung von Klassen und fortgeschrittene Konzepte II.4.1 Unterklassen und Vererbung

Mehr

Institut für Programmierung und Reaktive Systeme. Java 6. Markus Reschke

Institut für Programmierung und Reaktive Systeme. Java 6. Markus Reschke Institut für Programmierung und Reaktive Systeme Java 6 Markus Reschke 13.10.2014 OOP Objekte = Verhalten (durch Methoden) + Daten (durch Attribute) Klassen = Baupläne für Objekte Kapselung von Programmteilen

Mehr

Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer. Programmiertechnik Schnittstellen, Vererbung & Polymorphismus für Fortgeschrittene

Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer. Programmiertechnik Schnittstellen, Vererbung & Polymorphismus für Fortgeschrittene Prof. Dr. Oliver Haase Karl Martin Kern Achim Bitzer Programmiertechnik Schnittstellen, Vererbung & Polymorphismus für Fortgeschrittene Motivation Aufgabe: Finanzbuchhaltungssystem für internationale Hotelkette

Mehr

Programmieren in Java

Programmieren in Java Programmieren in Java Vorlesung 11: Generic Methods Prof. Dr. Peter Thiemann Albert-Ludwigs-Universität Freiburg, Germany SS 2017 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 1 / 15 Inhalt

Mehr

! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4.

! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4. ! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4.4 Exceptions - 1 - Ausnahmen (Exceptions( Exceptions) Treten auf, wenn zur

Mehr

Programmieren 2 Java Überblick

Programmieren 2 Java Überblick Programmieren 2 Java Überblick 1 Klassen und Objekte 2 Vererbung 4 Innere Klassen 5 Exceptions 6 Funktionsbibliothek 7 Datenstrukturen und Algorithmen 8 Ein-/Ausgabe 9 Graphische Benutzeroberflächen 10

Mehr

Computeranwendung und Programmierung (CuP)

Computeranwendung und Programmierung (CuP) Computeranwendung und Programmierung (CuP) Übungsorganisation Bringen Sie Ihren Labtop in die Übungen mit! 09.10.2017 CuP - VO 2 Programmieren 1. Definition der Aufgabe, die das Programm lösen soll. 2.

Mehr

14 Abstrakte Klassen, finale Klassen, Interfaces

14 Abstrakte Klassen, finale Klassen, Interfaces Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält, heißt ebenfalls abstrakt. Für eine abstrakte Klasse

Mehr

Tag 8 Repetitorium Informatik (Java)

Tag 8 Repetitorium Informatik (Java) Tag 8 Repetitorium Informatik (Java) Dozent: Michael Baer Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018 Informatik-Repetitorium

Mehr

Übungsblatt 13. Abgabe / Besprechung in Absprache mit dem Tutor

Übungsblatt 13. Abgabe / Besprechung in Absprache mit dem Tutor Albert-Ludwigs-Universität Freiburg Institut für Informatik Einführung in die Informatik Sommersemester 2013 PD Dr. Cyrill Stachniss Dr. Rainer Kümmerle Übungsblatt 13 Abgabe / Besprechung in Absprache

Mehr

2.13 Vererbung. Rainer Feldmann Universität Paderborn Technische Informatik für Ingenieure (TIFI) WS 09/ Article

2.13 Vererbung. Rainer Feldmann Universität Paderborn Technische Informatik für Ingenieure (TIFI) WS 09/ Article 2.13 Vererbung Klassen modellieren Objekte der realen Welt. Diese sind oft hierarchisch gegliedert. Beispiel: Ein Verlag bietet Bücher und CDs an. Beide Medien sind Artikel des Verlages. Book author: String

Mehr

10.4 Konstante Objekte

10.4 Konstante Objekte 10.4 Konstante Objekte Genau wie bei einfachen Datentypen (int,double,...) kann man auch Objekte als const deklarieren. Eine solche Deklaration bedeutet, daß alle Attribute so behandelt werden, als wären

Mehr

Beispiel: Zwischen der Oberklasse und der abgeleiteten Klasse besteht eine ist ein Beziehung. Eine abgeleitete Klasse stellt eine Spezialisierung der

Beispiel: Zwischen der Oberklasse und der abgeleiteten Klasse besteht eine ist ein Beziehung. Eine abgeleitete Klasse stellt eine Spezialisierung der Vererbung Vererbung ist ein Konzept der objektorientierten Programmierung,, die es ermöglicht neue Klassen von bereits vorhandenen Klassen abzuleiten. In einer abgeleiteten Klasse (subclass) muss nur spezifiziert

Mehr

14 Abstrakte Klassen, finale Klassen, Interfaces. Auswertung von Ausdrücken. Beispiel. Abstrakte Methoden und Klassen

14 Abstrakte Klassen, finale Klassen, Interfaces. Auswertung von Ausdrücken. Beispiel. Abstrakte Methoden und Klassen Auswertung von Ausdrücken Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält, heißt ebenfalls abstrakt.

Mehr

Erste Java-Programme (Java Wiederholung & Vererbung)

Erste Java-Programme (Java Wiederholung & Vererbung) Lehrstuhl Bioinformatik Konstantin Pelz Erste Java-Programme (Java Wiederholung & ) Tutorium Bioinformatik (WS 18/19) Konstantin: Konstantin.pelz@campus.lmu.de Homepage: https://bioinformatik-muenchen.com/studium/propaedeutikumprogrammierung-in-der-bioinformatik/

Mehr

Vorlesung Inf-B

Vorlesung Inf-B Vorlesung Inf-B stehn@mi.fu-berlin.de Quelle Diese Folien basieren auf dem Java-Tutorial Generics von Gilad Bracha http://java.sun.com/docs/books/tutorial/extra/generics/ 2 Motivierendes Beispiel List

Mehr

Einstieg in die Informatik mit Java

Einstieg in die Informatik mit Java 1 / 34 Einstieg in die Informatik mit Java Klassen mit Instanzmethoden Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 34 1 Definition von Klassen 2 Methoden 3 Methoden

Mehr

Polymorphismus 44. Function.hpp. #include <string>

Polymorphismus 44. Function.hpp. #include <string> Polymorphismus 44 #include Function.hpp class Function { public: virtual ~Function() {}; virtual const std::string& get_name() const = 0; virtual double execute(double x) const = 0; }; // class

Mehr

Einführung in die Programmierung

Einführung in die Programmierung Technische Universität München WS 2003/2004 Institut für Informatik Prof. Dr. Christoph Zenger Semestralklausur Einführung in die Programmierung Semestralklausur Java (Lösungsvorschlag) 1 Die Klasse ArrayList

Mehr

14 Abstrakte Klassen, finale Klassen, Interfaces

14 Abstrakte Klassen, finale Klassen, Interfaces Eine abstrakte Objekt-Methode ist eine Methode, für die keine Implementierung bereit gestellt wird. Eine Klasse, die abstrakte Objekt-Methoden enthält, heißt ebenfalls abstrakt. Für eine abstrakte Klasse

Mehr

Javakurs zu Informatik I. Henning Heitkötter

Javakurs zu Informatik I. Henning Heitkötter Javakurs zu Informatik I Arrays vergleichen Implementieren Sie folgende Methode, die prüft, ob die Elemente der beiden Arrays an jeder Position übereinstimmen: public static boolean identisch(int[] a,

Mehr

Sichtbarkeiten, Klassenmember und -methoden

Sichtbarkeiten, Klassenmember und -methoden Sichtbarkeiten, Klassenmember und -methoden Prof. Dr.-Ing. Thomas Schwotzer 11. November 2017 1 Einführung Wir haben uns mit Klassen und Objekten beschäftigt. Wir wissen nun, dass Objekte anhand von Klassen

Mehr

Einführung in die Programmierung Blockkurs Java

Einführung in die Programmierung Blockkurs Java Michael Bader 8. 12. April 2002 Dienstag Inhaltsübersicht Variablen: Membervariablen und lokale Variablen Referenzvariablen: Arrays und Objekte anlegen Definition von Funktionen: Methoden Konstruktoren

Mehr

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1 Kapitel 13 Listen Listen 1 Ziele Implementierungen für Listen kennenlernen Einfach verkettete und doppelt verkettete Listen verstehen Listen-Implementierungen in der Java-Bibliothek kennenlernen Durch

Mehr

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1 Kapitel 12 Listen Listen 1 Ziele Implementierungen für Listen kennenlernen Einfach verkettete und doppelt verkettete Listen verstehen Listen-Implementierungen in der Java-Bibliothek kennenlernen Durch

Mehr