Interface bzw. Schnittstelle anschaulich: Hüllenklasse

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

der Universität Oldenburg
DVG Einfache Klassen Einfache Klassen. DVG Einfache Klassen 2 Strukturen Beispiel: Personendaten bestehen aus –String name –String vorname.
Progwerkstatt JAVA Klasse, Objekte, Konstruktoren, Methoden
Abstrakte Klassen HS Merseburg (FH) WS 06/07.
Java: Objektorientierte Programmierung
Java: Grundlagen der Objektorientierung
Vererbung.
SWITCH - Anweisung.
Abstrakte Klassen.
Klassenvariable (auch Klassendaten bzw. statische Attribute genannt) und statische Methoden.
Ein Beispiel in Java.
Erweiterte Zuweisungskompatibilität
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Assoziationen (Beziehungen) 1 : n. Zu einem Auto gibt es mehrere Fahrer (2) und zu diesen 2 Fahrern gibt es genau dieses Auto.
WHILE - Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
Polymorphie (Vielgestaltigkeit)
Assoziationen (Beziehungen). Zwischen Objekten kann es eine Beziehung geben.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
FOR Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
Exceptions. import java.sql.*; public class MyException{ boolean b; Statement stat; public MyException(){ b = stat.execute("xyz"); } Beim Übersetzen dieses.
DO...WHILE Anweisung.
ARRAY oder FELD oder VEKTOR
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 5 Polymorphismus Sommersemester 2003 Lars Bernard.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
Einführung in die OOP in Java
Programmieren mit JAVA
Programmieren mit JAVA
Vererbung Spezialisierung von Klassen in JAVA möglich durch
PKJ 2005/1 Stefan Dissmann Klassenhierarchie Person Kunde Goldkunde Lieferant Object.
Abstrakte Klassen DVG
DVG Interfaces. DVG mehrfache Vererbung 4 Mehrfache Vererbung ist die Ableitung einer Klassen von mehreren anderen Klassen. –farbigerPunkt.
DVG Einführung in Java1 Einführung in JAVA.
07-GraphischeObjekte Graphische Objekte in EMMA301Paint.
Abstrakte Klassen, Interface
DVG Klassen und Objekte
DVG Einfache Klassen 1 Einfache Klassen. 2DVG Einfache KlassenStrukturen Beispiel: Personendaten bestehen aus String name String name.
Klassen 02 - Klassen.
Java in 9 Folien Besser: Online-Buch Go to Java 2.
Seite 1 Interface - Konzept Ein Interface führt einen neuen Datentyp ein: interface Frau {... } Das Interface enthält Deklarationen ( keine Definitionen.
Entwurfs- und Implementationsdiagramme
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
EPROG Tutorium #6 Philipp Effenberger
EPROG Tutorium #5 Philipp Effenberger
CuP - Java Vierte Vorlesung Entspricht ungefähr Kapitel 2.1 des Skriptums Montag, 14. Oktober 2002.
Programmiervorkurs WS 2014/15 Instanzmethoden
CuP - Java Achte Vorlesung Entspricht ungefähr Kapitel 4.1 des Skriptums Montag, 28. Oktober 2002.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
Informatik I : Software höhere Programmiersprachen Java Klassen: hat Methoden (Funktionen) und Daten (Variablen) es kann mehrere Klassen geben nur eine.
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Java-Kurs Übung Besprechung der Hausaufgabe
Einführung in die Programmierung mit Java
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Abstrakte Klassen und das Interface-Konzept
Java Programme nur ein bisschen objektorientiert.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Vererbung in Java. public abstract class Form { protected int breite; protected int hoehe; protected String farbe; /** * Erzeuge eine Form der Breite.
Klassenvariable.
Konstruktoren.
OOP II.
Java-Kurs Übung Klassen und Objekte: Vererbung (Fortsetzung)
Es gibt Klassen, die mit der Entwicklungsumgebung ausgeliefert werden
1. Die rekursive Datenstruktur Liste 1
 Präsentation transkript:

Interface bzw. Schnittstelle anschaulich: Hüllenklasse

Ein sogenanntes Konsolenprogramm gibt - im Gegensatz zu einer grafischen Oberfläche - mit System.out.println(...) seine Ausgabe auf dem Bildschirm aus. Ein Programmierer, der ein Konsolenprogramm schreibt und aufmerksam ist (d.h. das Programm auch testet), sollte folgendes beachten:

Jede Klasse sollte - zu Testzwecken - jeweils die Methode printAllAttributs() enthalten, mit der die Attribute einer Klasse auf dem Bildschirm ausgegeben werden. Um den Programmierer zu zwingen, diese Methode zu implementieren (auszuprogrammieren), könnte man sie (den Methodenkopf) in einer abstrakten Klasse ablegen.

Nutztier Kuh Henne + printAllAttributs(): void Abstrakte Klassen und Methoden werden durch eine kursive Schreibweise gekennzeichnet oder durch den Bezeichner {abstract}, siehe Präsentation zu abstrakte Klassen Kuh +printAllAttributs():void Henne +printAllAttributs():void

Es ist aber nicht besonders sinnvoll printAllAttributs() als abstrakte Methode in die Klasse Nutztier zu stecken, da printAllAttributs() nicht speziell was mit der Klasse Nutztier zu tun hat, sondern in jeder Klasse vorkommt.

Es ist sinnvoller, diese Methode z. B Es ist sinnvoller, diese Methode z.B. in eine mit Druckbar bezeichnete Klasse zu stecken und von dieser Klasse die Methode printAllAttributs() zu erben. Da es in Java keine Mehrfachvererbung gibt, (konkret: wenn z.B. Kuh Unterklasse von Nutztier ist, kann Kuh nicht auch noch Unterklasse von der Klasse Druckbar sein), hat man sich den Trick mit dem Interface einfallen lassen.

In UML dargestellt ergibt dies (siehe nächste Folie): Bemerkung: Interfaces werden mit Hilfe von gestrichelten Linien dargestellt. Näheres siehe einige Folien weiter hinten.

<<interface>> Druckbar + printAllAttributs(): void Mit Klasse statt Interface hätte man eine Mehrfachvererbung Nutztier +printAllAttributs():void Kuh +printAllAttributs():void Henne +printAllAttributs():void

Eine Klasse kann beliebig viele Interfaces "einbinden" (mit dem Wort implements). Ein Interface ist so etwas ähnliches wie eine Klasse, nur dass dort von den Methoden nur die Methodenköpfe (mit den Parametern) angegeben werden dürfen (wie bei abstrakten Klassen). Ein Interface ist von der Sache her abstract und es ist deswegen nicht nötig es (und seine Methoden) als abstract zu deklarieren.

Die komplette Methode (mit Methodenrumpf) muss dann in der Klasse implementiert werden, die dieses Interface "einbindet" (mit implements). Ein Interface besteht im Unterschied zu einer abstrakten Klasse nur aus Methodenköpfen (mit den Parametern).

Ein Interface muss in einer eigenen Datei erstellt werden, wenn es public ist (es gilt also das gleiche Schema wie bei Klassen: 2 public Klassen können nicht in der gleichen Datei sein). Ein Interface ist von der Sache her abstract und es ist deswegen nicht nötig es als abstract zu deklarieren (dies sollte auch nicht gemacht werden). In einem Interface dürfen nur Klassenvariable (mit public, static, final), aber keine "normalen" Attribute definiert werden.

Alle Methoden in Interfaces sind automatisch abstrakt und public Alle Methoden in Interfaces sind automatisch abstrakt und public. Deshalb sollten die Bezeichner public und abstract bei der Deklaration von Methoden in Interfaces nicht verwendet werden. Dagegen müssen bei der Implementierung (Ausprogrammierung) einer Schnittstelle die Methoden in den Unterklassen mit public implementiert werden, da die Methoden in Interfaces immer automatisch public sind.

Bemerkung: Ein StandardInterface ist ein Interface des Java-Systems, d Bemerkung: Ein StandardInterface ist ein Interface des Java-Systems, d.h. eines Interfaces das mit der Entwicklungsumgebung ausgeliefert wird, wie z.B: Comparable, Serializable

Benennung von Interfaces: Zwar kann man (abgesehen von bestimmten Sonderzeichen) Interfaces benennen wie man will, doch könnte man folgenden Vorschlag berücksichtigen: 1) Interface endet mit ...bar bzw. auf englisch ...able Beispiel: Printable Diese Begrifflichkeit ist dann analog zu StandardInterfaces wie Comparable, Serializable, usw.

2) Interface beginnt mit I (wie Interface) Beispiel: IKfz INutztier

Beispiel: (Wegen der übersichtlichen Darstellung werden im Folgenden einige set- und get-Methoden weggelassen)

class Henne extends Nutztier implements Druckbar{ private double legeLeistung; public Henne(String pName, double pLegeLeistung){ super(pName); legeLeistung=pLegeLeistung; } public double getTierwert(){ return(2 * legeLeistung); public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Legelst.=" +legeLeistung);

class Kuh extends Nutztier implements Druckbar{ private double milchLeistung; public Kuh(String pName, double pMilchLeistung){ super(pName); milchLeistung=pMilchLeistung; } public double getTierwert(){ return(100 * milchLeistung); public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Milchlst= " +milchLeistung);

Warum muss diese Methode implementiert werden? abstract class Nutztier implements Druckbar{ private String name; public Nutztier(String pName){ name = pName; } abstract public double getTierwert(); public double getGewinn(){ return(0.1*getTierwert()); public void printAllAttributs(){ System.out.println("Name des Nutztiers = "+name); Warum muss diese Methode implementiert werden? Weil nur der Methodenkopf im Interface Druckbar angegeben wird, muss die Methode in der Unterklasse ausprogrammiert werden. Frage: Gibt es hier aber auch noch einen weiteren Grund?

abstract class Nutztier implements Druckbar{ private String name; public Nutztier(String pName){ name = pName; } abstract public double getTierwert(); public double getGewinn(){ return(0.1*getTierwert()); public void printAllAttributs(){ System.out.println("Name des Nutztiers = "+name); In den Unterklassen wird mit super. printAllAttributs() die Methode printAllAttributs() der Oberklasse aufgerufen.

public class MainInterface{ public static void main( String[] args){ Kuh myk=new Kuh("Elsa", 10); Henne myh=new Henne("Ute", 1); myk.printAllAttributs(); myh.printAllAttributs(); } Was wird auf dem Bildschirm ausgegeben ?

public class MainInterface{ public static void main( String[] args){ Kuh myk=new Kuh("Elsa", 10); Henne myh=new Henne("Ute", 1); myk.printAllAttributs(); myh.printAllAttributs(); } Name der Nutztiers = Elsa Milchlst.= 10 Name der Nutztiers = Ute Legelst.= 1

und hier das Interface:

public interface Druckbar{ void printAllAttributs(); } Bezeichner abstract wird weggelassen public interface Druckbar{ void printAllAttributs(); } Bezeichner public und abstract werden weggelassen

Diskussion: Was soll das Interface Diskussion: Was soll das Interface? Zu was braucht man hier das Interface? Man kann es doch weglassen, und die Methode printAllAttributs trotzdem verwenden, oder?

Das ist richtig! Deshalb gibt es nachher ein Beispiel, das nicht ohne Interface auskommt !!!

Darstellung eines Interface in UML

<<interface>> Druckbar Kuh Henne + printAllAttributs(): void Ein Interface wird mit <<interface>> bezeichnet und mit einem Pfeil mit gestrichelten Linien auf das Interface gezeigt. Kuh +printAllAttributs():void Henne +printAllAttributs():void

Hierarchie (Zuweisungskompatibilität)

public class MainInterface{ public static void main( String[] args){ Kuh myk=new Kuh("Elsa", 10); Henne myh=new Henne("Ute", 1); Druckbar aa1; Druckbar aa2; aa1 = myk; aa2 = myh; myh = aa2; myk = aa1; } } Welche Anweisungen sind korrekt, welche falsch? (Compiler meldet Fehler) // auch möglich: // Druckbar aa1 = myk; // Druckbar aa2 = myh; Diese 2 Anweisungen sind richtig: "Obertyp = Untertyp" Diese 2 Anweisung sind falsch. "Untertyp != Obertyp"

Weiteres Beispiel:

Zusätzlich zu dem Beispiel mit den Nutztieren soll eine Klassenmethode void printObjekte(... feld) in der Klasse Bildschirmausgabe erstellt werden. Diese gibt alle Attribute der Objekte des Feldes feld auf Konsole aus, indem die obige Methode printAllAttributs() verwendet wird.

Da die Methode printObjekte( Da die Methode printObjekte(... feld) eine Klassenmethode ist, wird sie nicht durch ein Objekt aufgerufen, sondern durch den Klassennamen, also z.B: Bildschirmausgabe.printObjekte(feld);

class Bildschirmausgabe{ public static void printObjekte(... feld){ ... } } Da diese Methode eine Klassenmethode ist, muß sie den Bezeichner static haben Welchen Typ (Datentyp) muss das Array feld haben? Wäre der Datentyp Henne sinnvoll? Nein, denn die Methode soll für ein Array mit dem Datentyp Kuh oder Henne funktionieren.

Wäre dann der Datentyp "Nutztier" sinnvoll? class Bildschirmausgabe{ public static void printObjekte(... feld){ ... } } Da diese Methode eine Klassenmethode ist, muß sie den Bezeichner static haben Wäre dann der Datentyp "Nutztier" sinnvoll? Nein, denn die Methode soll für ein Array beliebigen Datentyps (nicht nur Kuh bzw. Henne) funktionieren. Sondern z.B. für beliebige (selbstgebastelte) Klassen, wie z.B. Auto, Kühlschrank, Buch, Blume, Mensch, ...

Kann man einen Datentyp angeben, den sowohl Kuh als auch Henne (als auch weitere selbstgebastelte Klassen) als "Oberdatentyp" besitzt? class Bildschirmausgabe{ public static void printObjekte(... feld){ ... } } Ja, man muß nur bei Kuh und Henne (oder einer anderen Klasse) das Interface Druckbar implementieren, dann gilt: Kuh ist "Untertyp" vom Obertyp "Druckbar" Henne ist "Untertyp" vom Obertyp "Druckbar" Das Array feld muß also vom Typ "Druckbar" sein !

Also wird die Klasse Bildschirmausgabe wie folgt implementiert:

for(i=0;i<feld.length;i++){ feld[i].printAllAttributs(); } class Bildschirmausgabe{ public static void printObjekte( feld){ int i; } } Druckbar[] for(i=0;i<feld.length;i++){ feld[i].printAllAttributs(); } In der Methode printObjekte(...) wird die Methode printAllAttributs(...) verwendet! Druckbar besitzt diese Methode, also hat feld den Datentyp Druckbar[] Zwischenfrage: Muß feld (besser jedes Element davon) vom Datentyp Druckbar sein oder kann es auch ein Oberdatentyp davon sein wie z.B. Object, die Mutter aller Klassen, also ...

for(i=0;i<feld.length;i++){ class Bildschirmausgabe{ public static void printObjekte( feld){ int i; } } Object[] for(i=0;i<feld.length;i++){ ((Druckbar) feld[i]). printAllAttributs(); } Da das übergebene Feldelement feld[i] die Methode printAllAttributs(...) verwendet, sollte (damit es keine Fehler gibt) feld[i] vom Datentyp Druckbar sein. Da der Datentyp (Klasse) Object kein printAllAttributs(...) besitzt, muß also folgender Downcast gemacht werden ...

Frage: Muß Druckbar ein Interface sein, oder kann es auch eine abstrakte Klasse oder einfach nur eine "einfache" Klasse sein? Dazu schauen wir uns das UML-Diagramm an.

<<interface>> Druckbar + printAllAttributs(): void Mit Klasse statt Interface hätte man eine Mehrfachvererbung also kann Druckbar keine Klasse bzw. abstrakte Klasse sein Nutztier +printAllAttributs():void Kuh +printAllAttributs():void Henne +printAllAttributs():void

Das gesamte Programm (Klasse Henne, Kuh, Nutztier ähnlich wie oben; Klasse Bildschirm kommt neu hinzu)

package interface10; public class MainInterface10 { public static void main(String[] args){ Druckbar[] feld = new Druckbar[2]; Kuh myk=new Kuh("Elsa", 100); Henne myh=new Henne ("Frida", 1); feld[0] = myk; feld[1] = myh; Bildschirmausgabe.printObjekte(feld); }

class Nutztier implements Druckbar{ private String name; public Nutztier(String pname){ name = pname; } public void printAllAttributs(){ System.out.println("Name des Nutztiers = "+name); Klasse kann auch abstrakt sein. In diesem Zusammenhang ist dies völlig egal. Aus Gründen einer einfachen Demonstration wurden in den Klassen Nutztier, Kuh und Henne einige Methoden (im Vergleich zum obigen Programm) weggelassen (wie z.B: getTierwert())

class Kuh extends Nutztier implements Druckbar{ private double milchLeistung; public Kuh(String pName, double pMilchLeistung){ super(pName); milchLeistung =pMilchLeistung; } public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Milchleistung= "+milchLeistung);

class Henne extends Nutztier implements Druckbar{ private double legeLeistung; public Henne(String pName, double pLegeLeistung){ super(pName); legeLeistung =pLegeLeistung; } public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Legeleistung= "+legeLeistung);

class Bildschirmausgabe{ public static void printObjekte(Druckbar[] feld){ int i; for(i=0;i<feld.length;i++){ feld[i].printAllAttributs(); }

und hier das Interface:

public interface Druckbar{ void printAllAttributs(); }

Frage: Hätte man das Design des letzten Programms so abändern können, daß Druckbar kein Interface, sondern eine Klasse bzw. abstrakte Klasse sein kann, man also ohne Interface auskommt?

Druckbar + printAllAttributs(): void Druckbar ist hier kein Interface sondern eine Klasse bzw. abstrakte Klasse Warum ist dieses Design schlecht? Nutztier +printAllAttributs():void Weil ein Nutztier inhaltlich betrachtet ... kein Druckbar ist. Man kann zwar sagen: Kuh +printAllAttributs():void Henne +printAllAttributs():void

Druckbar + printAllAttributs(): void Ein Nutztier ist ein Druckbar. Selbst wenn man statt Druckbar einen besseren Namen wählt, Eine Kuh ist ein Nutztier, aber es ist sinnlos zu sagen: Nutztier +printAllAttributs():void wie z.B. Drucker, gibt dies auch keinen Sinn! Kuh +printAllAttributs():void Henne +printAllAttributs():void

und hier das Programm:

package ohneinterface10; public class MainOhneInterface10 { public static void main(String[] args){ Druckbar[] feld = new Druckbar[2]; Kuh myk=new Kuh("Elsa", 100); Henne myh=new Henne ("Frida", 1); feld[0] = myk; feld[1] = myh; Bildschirmausgabe.printObjekte(feld); } Keine Änderung (im Vergleich zum letzten Programm)

class Nutztier extends Druckbar { private String name; public Nutztier(String pname){ name = pname; } public void printAllAttributs(){ System.out.println("Name des Nutztiers = "+name); implements Druckbar fehlt (im Vergleich zum letzten Programm)

class Kuh extends Nutztier { private double milchLeistung; public Kuh(String pName, double pMilchLeistung){ super(pName); milchLeistung =pMilchLeistung; } public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Milchleistung= "+milchLeistung); implements Druckbar fehlt (im Vergleich zum letzten Programm)

class Henne extends Nutztier { private double legeLeistung; public Henne(String pName, double pLegeLeistung){ super(pName); legeLeistung =pLegeLeistung; } public void printAllAttributs(){ super.printAllAttributs(); System.out.println("Legeleistung= "+legeLeistung); implements Druckbar fehlt (im Vergleich zum letzten Programm)

class Bildschirmausgabe{ public static void printObjekte(Druckbar[] feld){ int i; for(i=0;i<feld.length;i++){ feld[i].printAllAttributs(); } Keine Änderung (im Vergleich zum letzten Programm)

class Druckbar{ public void printAllAttributs(){ System.out.println("schrott"); } // public abstract void printAllAttributs(); Druckbar ist jetzt kein Interface mehr, sondern eine Klasse (und hätte dann auch einen anderen (selbstsprechenden) Namen verdient). Man könnte printAllAttributs() auch abstract machen und hätte dann eine abstrakte Klasse

Was fehlt jetzt noch? Ein Beispiel, wo man nicht auf ein Interface verzichten kann. Können Sie so ein Beispiel konstruieren?

Henne, Kuh und Krokodil (Fleisch, Leder) sind Nutztiere Henne, Kuh und Krokodil (Fleisch, Leder) sind Nutztiere. Nur Kühe und Hennen können Freunde (zum Spielen mit den Bauernkinder) der Tiere sein, nicht aber ein Krokodil (warum wohl?). Die Freunde machen Geschenke an die Bauernkinder: Kuh: Milchleistung / 2 Henne: Legeleistung * 3

Es sollen ein paar Freunde erstellt werden Es sollen ein paar Freunde erstellt werden. Dann sollen die Geschenke dieser Freunde auf dem Bildschirm ausgegeben werden. Aber zuerst das UML:

Freund Nutztier Kuh Henne Krokodil Dies ist der Ausgangspunkt: Kuh, Henne und Krokodil ist jeweils ein Nutztier. Wo benötigt man die Methode getGeschenk()? Wie muß man Freund in dieses UML einfügen? Wo gibt es Probleme? Freund Nutztier +getGeschenk() Kuh Henne Krokodil +getGeschenk() +getGeschenk()

Freund Nutztier Kuh Henne Krokodil Mit Klasse Freund hat man eine Mehrfachvererbung Was muß man also tun? Aus Freund ein Interface machen! (mit dem selbstsprechenden Namen IFreund) Freund Nutztier +getGeschenk() Kuh Henne Krokodil +getGeschenk() +getGeschenk()

<<interface>> IFreund Nutztier +getGeschenk() Kuh Henne Krokodil +getGeschenk() +getGeschenk()

Und hier das Programm:

package interface20; public interface IFreund { double getGeschenk(); void printGeschenk(); } Das Interface (in einer eigenen Datei)

package interface20; public class MainInterface20 { public static void main(String[] args) { int i; IFreund freunde[] = new IFreund[4]; Nutztier[] nutztiere = new Nutztier[3]; nutztiere[0] = new Henne("Pute", 3); nutztiere[1] = new Henne("Elsa", 200); nutztiere[2] = new Krokodil("Schnappi", 50); freunde[0]= new Kuh("FreundMilka", 10); freunde[1]= new Henne("FreundUte", 5); freunde[2]= new Henne("FreundIda", 4); freunde[3]= new Kuh("FreundSusi", 34); for(i=0; i<freunde.length; i++){ freunde[i].printGeschenk(); } "polymorphe Methode" freunde[i] tritt verschiedengestaltig auf (als Henne oder Kuh)

abstract class Nutztier{ private String name; public Nutztier(String pname) { name = pname; } abstract double getTierwert(); public void printAllAttributs(){ System.out.println("Nutztier: "); public void setName(String pName) { name = pName; public String getName() { return (name);

class Kuh extends Nutztier implements IFreund { private double milchLeistung; public Kuh(String pName, double pMilchLeistung) { super(pName); milchLeistung = pMilchLeistung; } public double getMilchLeistung() { return milchLeistung; public void setMilchLeistung(double milchLeistung) { this.milchLeistung = milchLeistung;

public double getTierwert() { return (100 * milchLeistung); } public void printAllAttributs() { System.out.println("Kuhname=" + getName() + " Milchleistung=" + milchLeistung);

// Interface verlangt Implementierung public double getGeschenk() { return (milchLeistung / 2.0); } public void printGeschenk() { System.out.println("Kuhname= " + getName() + " Geschenk= " + getGeschenk());

private int legeLeistung; super(pName); legeLeistung = pLegeLeistung; class Henne extends Nutztier implements IFreund { private int legeLeistung; public Henne(String pName, int pLegeLeistung) { super(pName); legeLeistung = pLegeLeistung; } public int getLegeLeistung() { return legeLeistung; public void setLegeLeistung(int legeLeistung) { this.legeLeistung = legeLeistung; public double getTierwert() { return (2 * legeLeistung);

// Zu Testzwecken public void printAllAttributs() { System.out.println("Hennename=" + getName() + " Legeleistung=" + legeLeistung); } // Interface verlangt Implementierung public double getGeschenk() { return (3 * legeLeistung); public void printGeschenk() { + " Geschenk=" + getGeschenk());

class Krokodil extends Nutztier { private int fleischmenge; public Krokodil(String pName, int pFleischmenge) { super(pName); fleischmenge = pFleischmenge; } public double getTierwert() { return (20 * fleischmenge); // Zu Testzwecken public void printAllAttributs() { System.out.println("Krokodilname=" + getName() + " Fleischmenge=" + fleischmenge);