# 97 Kap. 13 Schnittstellen Kap. 13.1 Trennung von Spezifikation und Implementierung Kap. 13.2 Ein weiterführendes Beispiel Kap. 13.3 Aufbau einer Schnittstelle Kap. 13.4 Verwendung von Schnitttstellen Kap. 13.5 Vergleich Schnittstelle und abstrakte Basisklasse # 98 Kap. 13.1 Trennung von Spezifikation und Implementierung Beim Entwurf objektorientierter Systeme unterscheidet man: • konzeptionelle Sicht, d.h. welche Klassen werden benötigt und welche Beziehungen unter ihnen sind nötig. • spezifizierende Sicht, d.h. welche Schnittstellen (Methodenköpfe eines Objektes) einer Klasse werden benötigt. • implementierende Sicht, d.h. wie werden die Methoden implementiert. Java unterstützt die Spezifikation durch das Sprachmittel des interface. Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 49 - # 99 Beispiel: // Datei: Punkt.java interface PunktSchnittstellen { public int getX(); public void setX (int i); } public class Punkt implements PunktSchnittstellen{ int x; public int getX (){ return x; } public void setX (int i){ x = i; } } #100 public static void main (String [] args) { Punkt p = new Punkt(); p.setX(3); System.out.println("x = " + p.getX()); } } <<interface>> PunktSchnittstellen Punkt Die Klasse Punkt implementiert das Interface PunktSchnittstellen. Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 50 - # 101 Eine Schnittstelle dient dem Entwurf der Software (Spezifikation). Sie enthält nur die Spezifikation der Methodenköpfe. Eine Klasse beinhaltet den Entwurf und die Implementierung der Methoden. D.h. im Unterschied zur Schnittstelle auch die Methodenrümpfe. Eine KLasse kann auch mehrere Interfaces implementieren. Die Implementation des gleichen Interfaces kann in verschiedenen Klassen verschieden sein. Damit ist das Protokoll einer Klasse die Gesamtheit ihrer Schnittstellen bildet, kann sich das Protokoll aus mehrerern Teilprotokollen zusammensetzen. Nach der Kompliierung steht die Schnittstelle PunktSchnittstellen als PunktSchnittstellen.class zur Verfügung! #102 Kap. 13.2 Ein weiterführendes Beispiel // Datei: Nachrichten.java interface NachrichtenQuelle { public void anmelden (NachrichtenEmpfaenger empf); public void sendeNachricht (String nachricht); } interface NachrichtenEmpfaenger { public void empfangeNachricht (String nachricht); } Alle Klassen, deren Objekte Nachrichten versenden können, implementieren die Schnittstelle NachrichtenQuelle. Eine Klasse Person kann die Schnittstelle NachrichtenEmpfaenger implementieren. Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 51 - # 103 NachrichtenQuelle anmelden() sendeNachricht() Radio Fernseher Zeitung Klassen, die die Schnittstelle NachrichtenQuelle implementieren # 104 NachrichtenEmpfaenger empfangeNachricht() Person Die Klasse Person implementiert die Schnittstelle NachrichtenEmpfaenger. Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 52 - # 105 // Datei: Zeitung.java import java.util.Vector class Zeitung implements NachrichtenQuelle { private String typ; private Vector vec = new Vector(); public Zeitung (String typ){ this.typ = typ; } public void anmelden(NachrichtenEmpfaenger empf){ vec.add (empf); } public void sendeNachricht(String nachricht){ for (int i = 0; i<vec.size(); i++){ NachrichtenEmpfaenger ref = (NachrichtenEmpfaenger) vec.elementAt (i); ref.empfangeNachricht (Nachricht); } } # 106 // Datei: Person.java class Person implements NachrichtenEmpfaenger { private String name; private String vorname; public Person(String name, String vorname){ this.name = name; this.vorname = vorname; } public void empfangeNachricht (String nachricht){ System.out.println("an " + name + " " + vorname + ": " + nachricht); } } Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 53 - # 107 // Datei: Test.java class Test { public static void main(String [] args){ Person p1 = new Person("Fischer", "Fritz"); Person p2 = new Person("Maier", "Hans"); Person p3 = new Person("Kunter", "Max"); Zeitung z1 = new Zeitung("-FAZ-"); z1.anmelden(p1);z1.anmelden(p2); Zeitung z2 = new Zeitung("-Suedkurier-"); z2.anmelden(p1);z2.anmelden(p2); System.out.println("FAZ Schlagzeile:"); z1.sendeNachricht("Haushaltsloch absehbar"); System.out.println("Suedkurier Schlagzeile:"); z2.sendeNachricht("Frieden in Afghanistan?"); } } Kap. 13.3 Aufbau einer Schnittstelle # 108 Schnittstellen bestehen aus zwei Teilen: • • der Schnittstellendeklaration dem Schnittstellenkörper mit Konstantendefinitionen und Methodendeklarationen. Eine Schnittstelle kann nur Methodendeklarationen und Konstanten enthalten. Die Datenfelder einer Schnittstelle sind immer implizit public static final. Methoden innerhalb einer Schnittstelle sind immer implizit public und abstract. abstract heißt, dass sie keinen Methodenrumpf besitzen. Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 54 - # 109 Beispiel: public interface NachrichtenQuelle { public static final int SPORT = 0; int POLIIK = 1; public int KULTUR = 2; public int ANZEIGEN = 3; public int GESAMT = 4; public int ZUFALL = (int) (Math.random()*5); // private int REGIONALES = 5; Fehler! // int SONSTIGES; Fehler! public void anmelden (NachrichtenEmpfaenger empf, int typ); void sendeNachricht(String nachricht); // ist implizit public abstract } Kap. 13.4 Verwendung von Schnitttstellen # 110 Eine Schnittstelle kann von jeder Klasse implementiert werden: z. B.: public class Punkt implements PunktSchnittstellen Es müssen alle Methoden der Schnittstelle implementiert werden, wenn sie instantiiert werden soll. Sonst wird die Klasse abstrakt, d.h. es können von ihr keine Objekte instantiiert werden. Eine Klasse, die eine Schnittstelle implementiert, erbt die in der Schnittstelle enthaltenen konstanten Datenfelder und abstrakten Methoden. Es kann aber keine Funktionalität geerbt werden, da Schnittstellen keine Methodenimplementierung beinhalten. Schnittstellen können wie Klassen mit extends vererbt werden: interface Vermittler extends NachrichtenQuelle { public void empfangeNachricht(String nachricht); } Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 55 - # 111 Kap. 13.5 Vergleich Schnittstelle und abstrakte Basisklasse Wird in einer Basisklasse nur die Schnittstelle von Methoden festgelegt und die eigentliche Implementierung einer, mehrerer oder aller Methoden erst in den abgeleiteten Klassen vorgenommen,dann spricht man von einer abstrakten Basisklasse. Sie können nicht implementiert werden; mit ihren Referenzen kann aber gearbeitet werden. Methoden ohne Methodenrumpf müssen mit dem Schlüsselwort abstract deklariert werden Abstrakte Basisklassen müssen mit dem Schlüsselwort abstract deklariert werden. # 112 Beispiel: // Datei: Abstrakt.java abstract class A { A(){System.out.print("Konstruktor A, ");} abstract void testPrint(int x); } class B extends A { B(){System.out.println("Konstruktor B");} void testPrint(int x){ System.out.println("x: " + x); } } public class Abstrakt { public static void main(String [] args){ // A a = new A(); B b = new B();A c = new B();b.testPrint(5); } } // Ausgabe: Konstruktor A, Konstruktor B // Konstruktor A, Konstruktor B // x: 5 Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 56 - # 113 Ergänzung: Aggregation, Komposition und Vererbung A B C D Vererbungshierarchie Die Klassen B, C, D sind von A abgeleitet # 114 A B C D Aggregationshierarchie Die Klasse A enthält Referenzen auf Objekte der Klassen B, C, D Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 57 - #115 Bei einer Komposition ist die Lebensdauer des zusammengesetzten Objektes identisch mit der Lebensdauer der Komponenten. Bei einer Aggregation können die Teile länger leben als das zusammengesetzte Objekt. In Java sind nur Aggregationen möglich, da eine Klasse nur Referenzen auf Objekte enthalten kann. Nach Zerstörung des zusammengesetzten Objektes können die Teile weiter existieren. # 116 Dreieck p1:Punkt p2:Punkt p3:Punkt Beispiel einer Aggregationshierarchie Die Klasse Dreieck enthält Referenzen auf 3 Objekte der Klasse Punkt: public class Dreieck { Punkt p1, p2, p3; ..... } Harms: "SoftwareEntwicklung", SWENT, WS 2001/02 - 58 -