From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100058.html | 488 +++++++++++++++++++++ 1 file changed, 488 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100058.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100058.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100058.html b/Master/Reference Architectures and Patterns/hjp5/html/k100058.html new file mode 100644 index 0000000..ea6c9ef --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100058.html @@ -0,0 +1,488 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 9 - OOP III: Interfaces +
+
+ + + + +

9.1 Grundlagen +

+
+ +
+ +

+Es wurde bereits erwähnt, dass es in Java keine Mehrfachvererbung +von Klassen gibt. Die möglichen Schwierigkeiten beim Umgang mit +mehrfacher Vererbung und die Einsicht, dass das Erben nichttrivialer +Methoden aus mehr als einer Klasse in der Praxis selten zu realisieren +ist, haben die Designer dazu veranlaßt, dieses Feature nicht +zu implementieren. Andererseits sah man es als wünschenswert +an, dass Klassen eine oder mehrere Schnittstellendefinitionen erben +können, und hat mit den Interfaces ein Ersatzkonstrukt +geschaffen, das dieses Feature bietet. + + + + +

9.1.1 Definition eines Interface

+ +

+Ein Interface ist eine besondere Form einer Klasse, die ausschließlich +abstrakte Methoden und Konstanten enthält. Anstelle des Schlüsselwortes +class +wird ein Interface mit dem Bezeichner interface +deklariert. Alle Methoden eines Interface sind implizit abstrakt und +öffentlich. Neben Methoden kann ein Interface auch Konstanten +enthalten, die Definition von Konstruktoren ist allerdings nicht erlaubt. + +

+Wir wollen uns ein einfaches Beispiel ansehen. Das folgende Listing +definiert ein Interface Groesse, +das die drei Methoden laenge, +hoehe und breite +enthält: + + +

+ + + + + +
+ +
+001 /* Groesse.java */
+002 
+003 public interface Groesse
+004 {
+005   public int laenge();
+006   public int hoehe();
+007   public int breite();
+008 }
+
+
+Groesse.java
+ +Listing 9.1: Definition eines Interface

+ +

+Diese Definition ähnelt sehr einer abstrakten Klasse und dient +dazu, eine Schnittstelle für den Zugriff auf die räumliche +Ausdehnung eines Objekts festzulegen. Wir wollen uns an dieser +Stelle keine Gedanken über komplizierte Details wie zu verwendende +Maßeinheiten oder Objekte mit mehr oder weniger als drei Dimensionen +machen. + + + + +

9.1.2 Implementierung eines Interface

+ +

+Durch das bloße Definieren eines Interface wird die gewünschte +Funktionalität aber noch nicht zur Verfügung gestellt, sondern +lediglich beschrieben. Soll diese von einer Klasse tatsächlich +realisiert werden, muss sie das Interface implementieren . +Dazu erweitert sie die class-Anweisung +um eine implements-Klausel, +hinter der der Name des zu implementierenden Interfaces angegeben +wird. Der Compiler sorgt dafür, dass alle im Interface geforderten +Methoden definitionsgemäß implementiert werden. Zusätzlich +»verleiht« er der Klasse einen neuen Datentyp, der - wie +wir noch sehen werden - ähnliche Eigenschaften wie eine echte +Klasse hat. + +

+Eine beispielhafte Implementierung des Interfaces Groesse +könnte etwa von der schon bekannten Auto-Klasse +vorgenommen werden: + + +

+ + + + + +
+ +
+001 /* Auto2.java */
+002 
+003 public class Auto2
+004 implements Groesse
+005 {
+006   public String name;
+007   public int    erstzulassung;
+008   public int    leistung;
+009   public int    laenge;
+010   public int    hoehe;
+011   public int    breite;
+012 
+013   public int laenge()
+014   {
+015     return this.laenge;
+016   }
+017 
+018   public int hoehe()
+019   {
+020     return this.hoehe;
+021   }
+022 
+023   public int breite()
+024   {
+025     return this.breite;
+026   }
+027 }
+
+
+Auto2.java
+ +Listing 9.2: Implementierung eines Interface

+ +

+Wir haben die Klasse dazu um drei veränderliche Instanzmerkmale +erweitert, die es uns erlauben, die vom Interface geforderten Methoden +auf einfache Weise zu implementieren. Ebenso wie die Klasse Auto +könnte auch jede andere Klasse das Interface +implementieren und so Informationen über seine räumliche +Ausdehnung geben: + + +

+ + + + + +
+ +
+001 public class FussballPlatz
+002 implements Groesse
+003 {
+004   public int laenge()
+005   {
+006     return 105000;
+007   }
+008 
+009   public int hoehe()
+010   {
+011     return 0;
+012   }
+013 
+014   public int breite()
+015   {
+016     return 70000;
+017   }
+018 }
+
+
+FussballPlatz.java
+ +Listing 9.3: Die Klasse FussballPlatz

+ +

+Hier geben die Interface-Methoden konstante Werte zurück (in +der Annahme, dass alle Fußballplätze gleich groß +sind). Ebenso gut ist es möglich, dass die Größe von +anderen Instanzmerkmalen abhängig ist und zur Implementierung +des Interfaces etwas mehr Aufwand getrieben werden muss: + + +

+ + + + + +
+ +
+001 /* PapierBlatt.java */
+002 
+003 public class PapierBlatt
+004 implements Groesse
+005 {
+006   public int format; //0=DIN A0, 1=DIN A1 usw.
+007 
+008   public int laenge()
+009   {
+010     int ret = 0;
+011     if (format == 0) {
+012       ret = 1189;
+013     } else if (format == 1) {
+014       ret = 841;
+015     } else if (format == 2) {
+016       ret = 594;
+017     } else if (format == 3) {
+018       ret = 420;
+019     } else if (format == 4) {
+020       ret = 297;
+021     }
+022     //usw...
+023     return ret;
+024   }
+025 
+026   public int hoehe()
+027   {
+028     return 0;
+029   }
+030 
+031   public int breite()
+032   {
+033     int ret = 0;
+034     if (format == 0) {
+035       ret = 841;
+036     } else if (format == 1) {
+037       ret = 594;
+038     } else if (format == 2) {
+039       ret = 420;
+040     } else if (format == 3) {
+041       ret = 297;
+042     } else if (format == 4) {
+043       ret = 210;
+044     }
+045     //usw...
+046     return ret;
+047   }
+048 }
+
+
+PapierBlatt.java
+ +Listing 9.4: Die Klasse PapierBlatt

+

+ + + + + + + + + +
+ +

+Die Art der Realisierung der vereinbarten Methoden spielt für +das Implementieren eines Interface keine Rolle. Tatsächlich kommt +es ausgesprochen häufig vor, dass Interfaces von sehr unterschiedlichen +Klassen implementiert und die erforderlichen Methoden auf sehr unterschiedliche +Weise realisiert werden.

+ + + + +
 Hinweis 
+
+

+ + + + + + + + + + + +
+ +

+Eine Klasse kann ein Interface auch dann implementieren, wenn sie +nicht alle seine Methoden implementiert. In diesem Fall ist die Klasse +allerdings als abstract +zu deklarieren und kann nicht dazu verwendet werden, Objekte zu instanzieren.

+ + + + +
 Tipp 
+
+ + + + +

9.1.3 Verwenden eines Interface

+ +

+Nützlich ist ein Interface immer dann, wenn Eigenschaften +einer Klasse beschrieben werden sollen, die nicht direkt in seiner +normalen Vererbungshierarchie abgebildet werden können. Hätten +wir beispielsweise Groesse als +abstrakte Klasse definiert, ergäbe sich eine sehr unnatürliche +Ableitungshierarchie, wenn Autos, Fußballplätze und Papierblätter +daraus abgeleitet wären. Durch Implementieren des Groesse-Interfaces +können sie die Verfügbarkeit der drei Methoden laenge, +hoehe und breite +dagegen unabhängig von ihrer eigenen Vererbungslinie garantieren. + +

+Wir wollen uns ein einfaches Beispiel für die Anwendung des Interfaces +ansehen. Dazu soll eine Methode grundflaeche +entwickelt werden, die zu jedem Objekt, das das Interface Groesse +implementiert, dessen Grundfläche (Länge mal Breite) berechnet: + + +

+ + + + + +
+ +
+001 /* Listing0905.java */
+002 
+003 public class Listing0905
+004 {
+005   public static long grundflaeche(Groesse g)
+006   {
+007     return (long)g.laenge() * g.breite();
+008   }
+009 
+010   public static void main(String[] args)
+011   {
+012     //Zuerst erzeugen wir ein Auto2...
+013     Auto2 auto = new Auto2();
+014     auto.laenge = 4235;
+015     auto.hoehe = 1650;
+016     auto.breite = 1820;
+017     //Nun ein DIN A4-Blatt...
+018     PapierBlatt blatt = new PapierBlatt();
+019     blatt.format = 4;
+020     //Und zum Schluß einen Fußballplatz...
+021     FussballPlatz platz = new FussballPlatz();
+022     //Nun werden sie ausgegeben
+023     System.out.println("Auto:  " + grundflaeche(auto));
+024     System.out.println("Blatt: " + grundflaeche(blatt));
+025     System.out.println("Platz: " + grundflaeche(platz));
+026   }
+027 }
+
+
+Listing0905.java
+ +Listing 9.5: Verwendung eines Interface

+ +

+Das Programm erzeugt zunächst einige Objekte, die das Groesse-Interface +implementieren. Anschließend werden sie an die Methode grundflaeche +übergeben, deren Argument g +vom Typ Groesse ist. Durch diese +Typisierung kann der Compiler sicherstellen, dass nur Objekte »des +Typs« Groesse an grundflaeche +übergeben werden. Das ist genau dann der Fall, wenn das übergebene +Objekt dieses Interface implementiert. + +

+Die Ausgabe des Programms ist: + +

+Auto:  7707700
+Blatt: 62370
+Platz: 7350000000
+
+ + +

+An diesem Beispiel kann man bereits die wichtigste Gemeinsamkeit zwischen +abstrakten Klassen und Interfaces erkennen: Beide können im Programm +zur Deklaration von lokalen Variablen, Membervariablen oder Methodenparametern +verwendet werden. Eine Interface-Variable ist kompatibel zu allen +Objekten, deren Klassen dieses Interface implementieren. + +

+Auch der instanceof-Operator +kann auf Interfacenamen angewendet werden. Eine alternative Implementierung +der Methode grundflaeche, die +mit allen Objekttypen funktioniert, könnte dann etwa so aussehen: + + +

+ + + + +
+ +
+001 public static long grundflaeche(Object o)
+002 {
+003   long ret = 0;
+004   if (o instanceof Groesse) {
+005     Groesse g = (Groesse)o;
+006     ret = (long)g.laenge() * g.breite();
+007   }
+008   return ret;
+009 }
+
+
+ +Listing 9.6: Der instanceof-Operator auf Interfaces

+ +

+Diese Implementierung verhält sich für alle Objekte, die +das Interface Groesse implementieren, +so wie die vorige. Für alle übrigen Objekte wird 0 zurückgegeben. +


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3