Die Arten der Unterklasse Neritimorpha Koken, 1896 (Gastropoda ...
ABSTRAKTE KLASSEN UND 3. Kapitel...
Transcript of ABSTRAKTE KLASSEN UND 3. Kapitel...
TechnikenderProgrammentwicklung
Prof.Dr.WolfgangSchramm
ABSTRAKTEKLASSENUNDINTERFACES
3.Kapitel
1
Übersicht
1. ProgrammstrukturierungmitPaketen(packages)
2. Vererbung3. AbstrakteKlassenundInterfaces4. Ausnahmebehandlung5. Datenströme:dieJavaio-Bibliothek6. Multithreading7. InnereKlassen8. Collections9. Generics10. Reflection
2
LernzieledesKapitels
¨ Verstehen,waseineabstrakteMethodeistundwozusieeingesetztwird.
¨ AbstrakteKlassenundihreBedeutungverstehen.
¨ Verstehen,wasInterfacessindundwozusieeingesetztwerden.
¨ DenUnterschiedzwischenabstraktenKlassenundInterfacesverstehen.
¨ AbwägenwannInterfacesundwannabstrakteKlasseneingesetztwerden.
2
3
Inhalt
o AbstrakteKlassen¤ Definition,Bedeutung¤ EinsatzbereichvonabstraktenKlassen¤ Beispielszenario
o Interfaces¤ Definition,Bedeutung¤ EinsatzbereichvonInterfaces
o AbstrakteKlassenvs.Interfaces
4
AbstrakteMethoden,AbstrakteKlassen
o Abstrakte Methoden:¤ bestehenausschließlichausderDeklaration(=Schnittstelle),¤ enthaltenkeineImplementierung,d.h.der(Methoden-)Rumpfistleer¤ könnennurpublic oderprotected sein,¤ sindmitdemAttributabstract versehen,¤ könnennichtdirektaufgerufenwerden(→ dynamischeBindung).
o Abstrakte Klassen:¤ Klassen,dieeineabstrakteMethodeenthalten,¤ müssenselbstalsabstraktdeklariertwerden(abstract),¤ sindalsObjekttypzulässig,abereskönnenkeineObjekteder
abstraktenKlasseerzeugtwerden.
5
AbstrakteKlassen→ KonkreteKlassen
o AbstrakteKlassenkönnennichtinstanziiert werden.o Überschreiben einerabstrakten Methode ineiner
Unterklasse+ImplementierungdesfehlendenMethodenrumpfes:abstrakteMethodewirdkonkret.
o Unterklasse einerabstraktenKlasse¤ implementiertalle ihreMethodenoder¤ implementierteinenTeilihreMethoden→ istselbstabstrakt
(schrittweiseKonkretisierung).
o FürObjektevomTypabstrakterKlassen,dieeinObjekteinerabgeleitetenkonkretenKlassereferenzieren,könnenMethodenaufgerufenwerden(→ Polymorphismus).
6
AbstrakteKlassen– Wozu?
o AbstrakteKlassensindeinwichtigestechnischesKonzeptderobjektorientiertenSoftwareentwicklung.
o Siedienendazu,dieSchnittstellenkünftigerUnterklassenfestzulegen(wennmanz.B.nochkeineImplementierungangebenkannoderwill).
o SiesindquasieinMuster(TemplateMethod Pattern),dasvorgibt,welcheMethodeninUnterklassenimplementiertwerdenmüssen.
o ErstdieUnterklassenwissen,wiesichdieMethodengenauverhaltensollen.
o EineabstrakteKlassewirktwieeinSteckplatz,indenObjektederUnterklasseneingestecktwerden.
o Software,diesolcheSteckplätzebereitstellt=Framework.
7
AbstrakteKlassen:Motivation- Beispiel-Szenario
Linie
x2, y2 : float
Kreis
r : float
berechneFläche () : floatverdoppleFläche ()
Punkt
Quadrat
l : float
berechneFläche () : floatverdoppleFläche ()
Rechteck
länge, breite : float
berechneFläche () : floatverdoppleFläche ()
GeometrischeFigur
verschiebe ( dX, dY : float )
OffsetPunkt
x, y : float
offset4
Quelle: [Knauber]
8
BenutzungdergeometrischenObjekte
¨ BeabsichtigteVerwendung(Beispiel):GeometrischeFigur [] gf = new GeometrischeFigur[100];...for ( int i=0; i<100; i++ )
gf[i].verschiebe( 5, 0 );
¨ Aber:DerfolgendeCodewirdvomCompilernichtakzeptiert,auchwennnurKreise,QuadrateundRechteckeimArrayenthaltensind.
float sum = 0f;for ( int i=0; i<100; i++ )
sum += gf[i].berechneFläche();System.out.println( "Gesamtfläche: " + sum );
¨ Grund:NichtallegeometrischenObjektekönnenihreFlächeberechnen,derCompilerkannnichtgarantieren(erprüftnurdieDeklaration!),dassfürjedesObjekteineMethodeberechneFläche() existiert.
9
Lösung:EinführeneinerzusätzlichenKlasse
Linie
x2, y2 : float
Punkt
GeometrischeFigur
verschiebe ( dX, dY : float )
OffsetPunkt
x, y : float
offset4
Kreis
r : float
berechneFläche () : floatverdoppleFläche ()
Quadrat
l : float
berechneFläche () : floatverdoppleFläche ()
Rechteck
länge, breite : float
berechneFläche () : floatverdoppleFläche ()
10
Lösung:EinführeneinerzusätzlichenKlasse
Linie
x2, y2 : float
Punkt
GeometrischeFigur
verschiebe ( dX, dY : float )
OffsetPunkt
x, y : float
FigurMitFläche
berechneFläche () : floatverdoppleFläche ()
Es ist nicht sinnvoll,diese Klasse zuinstanziieren!
Sie sollte "abstrakt"bleiben.
offset4
Diese Methodenkönnen hier nicht(konkret) definiert
werden!Sie bleiben "abstrakt";
also muss auch dieKlasse abstrakt bleiben.
Kreis
r : float
berechneFläche () : floatverdoppleFläche ()
Quadrat
l : float
berechneFläche () : floatverdoppleFläche ()
Rechteck
länge, breite : float
berechneFläche () : floatverdoppleFläche ()
11
BenutzungderzusätzlichenKlasseFigurMitFläche
o BeabsichtigteVerwendung(Beispiel)FigurMitFläche [] fmf = new FigurMitFläche[100];...for ( int i=0; i<100; i++ )fmf[i].verschiebe( 5, 0 );
o DieVereinbarungvonfmf alsArrayvonFigurenmitFlächelässtnurnur Kreise,QuadrateundRechteckezu(keinePunkteundLinien)
float sum = 0f;for ( int i=0; i<100; i++ )sum += fmf[i].berechneFläche();
System.out.println( "Gesamtfläche: " + sum );
12
Beispiel:AbstrakteKlasse
o VomlogischenundvomimplementierungstechnischenGesichtspunktsinnvollà KlasseGeometrischeFigur :¤ AllebetrachtetenFigurenSIND(spezielle)geometrischeObjekte.¤ DieKlasseGeometrischeFigur fasstdieGemeinsamkeitenaller
speziellengeometrischenObjektezusammen:n AllebesitzeneinenUrsprungspunkt.n AllesindrelativzudiesemUrsprungspunktangelegtunddadurchverschiebbar.
¤ DerentsprechendeProgrammcode(AttributeundMethode)mussnureinmalgeschriebenwerdenundistzentralwartbar.
o Aber:Nichtsinnvoll,dieObjekteGeometrischeFigur zuerzeugen: "GeometrischeObjekte"existiereninderrealenWeltnicht,esgibtnurObjektederspezialisiertenUnterklassen.à abstrakteKlasseverhindertInstanziierung.
13
Implementierung(Teil1)
class OffsetPunkt {
float x, y;
OffsetPunkt( float x, float y ) {this.x = x;this.y = y;
}
void verschiebe(float dx, float dy) {this.x += dx;this.y += dy;
}
} // OffsetPunkt
class Punktextends GeometrischeFigur {
Punkt( float x, float y ) {super( x, y );
}
} // Punkt
class Test {
static void main( String[] args ) {Punkt p = new Punkt( 3, 4 );p.verschiebe( 2, 3 );
}
} // Test
abstract class GeometrischeFigur {
OffsetPunkt offset;
GeometrischeFigur( float x, float y ) {offset = new OffsetPunkt( x, y );
}
void verschiebe ( float dx, float dy ) {offset.verschiebe( dx, dy );
} // verschiebe
} // GeometrischeFigur
14
Beispiel:AbstrakteMethoden
o DieKlasse FigurMitFläche enthältdieMethodenberechneFläche undverdoppleFläche:¤ DieseMethodenkönnenhiernichtimplementiertwerden,
weilsiefürKreis,QuadratundRechteckunterschiedlichimplementiertwerdenmüssen.
® Methodenbleibenabstraktundmüssenauchabstraktdefiniertwerden:
abstract float berechneFläche ();abstract void verdoppleFläche ();
® Wennsie(mindestens)eineabstrakteMethodeenthält,mussdieKlasseselbstalsabstraktdefiniertwerden:
abstract class FigurMitFläche { … }
FigurMitFläche
berechneFläche () : floatverdoppleFläche ()
15
Übersicht:BeispielmitabstraktenKlassenundMethoden
Linie
x2, y2 : float
Kreis
r : float
berechneFläche () : floatverdoppleFläche ()
Punkt
Quadrat
l : float
berechneFläche () : floatverdoppleFläche ()
Rechteck
länge, breite : float
berechneFläche () : floatverdoppleFläche ()
GeometrischeFigur
verschiebe ( dX, dY : float )
OffsetPunkt
x, y : float
FigurMitFläche
berechneFläche () : floatverdoppleFläche ()
offset4
FigurMitFläche
berechneFläche () : float
verdoppleFläche ()
GeometrischeFigur
verschiebe ( dX, dY : float )
Kursive Schriftkennzeichnet abstrakteKlassen und Methoden.
16
AbstrakteKlassen– AchtungbeimKonstruktor
o AbstrakteKlassenkönnennichtinstanziiertwerden.o D.h.mankannkeinObjektderabstraktenKlassedurchden
Konstruktoraufruf mitnew erzeugen.o TrotzdemhabenabstrakteKlasseneinenKonstruktor.o GibtesinderabstraktenKlasseesnureinenselbstdefinierten
Konstruktorà ProgrammierermusssichexplizitumdenKonstruktoraufruf derabstraktenOberklassekümmern.
è BezüglichderKonstruktoraufrufe geltenfürabstrakteKlassendieselbenRegelnwiefürkonkreteKlassen.
17
Beispiel:Konstruktoren fürabstrakteKlassen
o DieKlasseFigurMitFläche beerbtdieKlasseGeometrischeFigur:¤ OhneexplizitenKonstruktorwirdFigurMitFläche
mitdemDefault-Konstruktorausgestattet.¤ DerDefault-Konstruktor(vonFigurMitFläche)
versucht,denDefault-KonstruktorderOber-klasse(GeometrischeFigur)aufzurufen.
¤ ZuGeometrischeFigur existiertkeinDefault-Konstruktor,daderfolgendeKonstruktordefiniertistundvondenKonstruktorenderKlassenPunkt undLinie benutztwird:GeometrischeFigur( float x, float y )
{ offset = new OffsetPunkt( x, y ); }
à FehlermeldungdurchdenCompiler.à FigurMitFläche benötigteinenKonstruktor,derdenexistierenden
KonstruktorvonGeometrischeFigur aufruft,obwohlFigurMitFläche eineabstrakteKlasseist!
FigurMitFläche
GeometrischeFigur
18
Implementierung(Teil2)
abstract class FigurMitFläche extends GeometrischeFigur {
FigurMitFläche ( float x, float y ) {super( x, y );
}
abstract float berechneFläche ();
abstract void verdoppleFläche ();
} // FigurMitFlächeclass Kreis extends FigurMitFläche {
float r;
Kreis( float x, float y, float r ) {super( x, y );this.r = r;
}
float berechneFläche () {return r*r*3.14f;
}
void verdoppleFläche () {r *= Math.sqrt( 2 );
}
} // Kreis
20
AbstrakteKlassenamBeispiel– wasistzubeachten1/2
o EskönnenObjektedefiniertwerden,dieInstanzenderKlasseFigurMitFläche aufnehmenkönnen:
FigurMitFläche f;o Folgerung:
DieseObjektekönnennurvoninstanziierbaren UnterklassenvonFigurMitFläche (z.B.Kreis,Quadrat)belegtwerden:
f = new Kreis( 2, 3, 4 );f = new Quadrat( 2, 3, 4 );
o Grund:ObjektevonKlassenkönnenüberalldortverwendetwerden,woObjekteihrerOberklassenverwendetwerdenkönnen(PrinzipderVererbungs-beziehung:einKreis isteinespezielleFigurMitFläche etc.).
21
AbstrakteKlassenamBeispiel– wasistzubeachten2/2
o AlleUnterklassenvonFigurMitFläche erbendieabstraktenMethoden.
o Konsequenzen:® DieUnterklassenmüssenalsabstraktdefiniertwerden,sofernsienicht
Implementierungenaller(geerbten)abstraktenMethodenzurVerfügungstellen(derCompilerprüftdas).
® Istein(instanziierbares)ObjektvonderUnterklassevonFigurMitFläche (alsodefacto voneinerseinerUnterklassen),soistgarantiert,dassdieMethodenberechneFläche undverdoppleFläche daraufanwendbarundimplementiertsind.
® Esistmöglich,mitFlächen-Figuren(d.h.mitObjektenkonkreterUnterklassen)zuarbeiten,ohnezuwissen,umwelcheArtvongeometrischemFlächen-Figuressichhandelt:siewerdendieOperationenverschiebe,berechneFläche undverdoppleFläche ausführenkönnen(sonsthättemansienichtinstanziierenkönnen).
® Esistmöglich,Teilprogrammezuschreiben,dievollkommenvonden(womöglichvielspäterdefinierten)tatsächlichinstanziierbaren Flächen-FigurenabstrahierenundnurdurchihreMethodenmitihnenkommunizieren.
22
VerwendungvonabstraktenKlassen
o ZurHierarchisierung/Strukturierung,wennInstanzennichtsinnvollsind.
o ZurVorgabevonSchnittstellenfür(spätere)Unterklassen.
23
Interfaces(Klassenschnittstellen)
o KannmansichalsvollständigabstrakteKlassenvorstellen:¤ AlleMethodeneinesInterfacesindabstrakt,d.h.siegebennureine
Schnittstellevor,habenaberkeineImplementierung.¤ AlleMethodensindautomatischabstraktundöffentlich(public).¤ Konstantensindzulässig(undautomatischpublic static final).¤ Datenfelder(Attribute)sindnichtzulässig.¤ Konstruktoren sindnichtzulässig.
o EineKlasseimplementiertdasInterface.o DieKlasse(odereineihrerUnterklassen)mussdieMethodendes
InterfaceüberschreibenundmitCodefüllen.o EinInterfacekannmehrereImplementierungenhaben,d.h.
verschiedeneKlassenkönnendieselbeSchnittstelleimplementieren.
o EineKlassekannmehrereSchnittstellenimplementieren® Mehrfachvererbung(i.S.v.Subtyping).
o EinöffentlichesInterface(public interface)stellteinenVertragzwischeneinerKlasseundihrenVerwenderndar.
o EineKlassekannmehrere,verschiedeneVerträgeeingehen.
24
Klassenvs.Interfaces– Subclassing vs.Subtyping
Subclassing =Implementierungsvererbung– Codevererbung– Implementierungsaspekt
Subtyping =Schnittstellenvererbung– VererbungvonfestgelegtemVerhalten– Entwurfsaspekt
Java– Klassen definieren Typ undImplementierung
Wenn derTyp einer Variablen ein Klassenname ist,dann kann dieVariableein Objekt dieser Klasse oder einer Unterklasse dieser Klassereferenzieren.
– InterfacesdefinierenTypenWenn derTyp einer Variablen durch einen Intefacenamen definiert ist,dann kann dieVariableObjekt aller Klassen,diedasInterfaceimplementieren,referenzieren.
25
BeispielfürdieDefinitioneinesInterface
public interface Groesse {
public int laenge();
public int hoehe();
public int breite();
}
• Festzulegen der Schnittstelle für den Zugriff auf die räumliche Ausdehnung eines Objekts.
• Diese Definition ähnelt sehr einer abstrakten Klasse.
• Durch das bloße Definieren eines Interfaces wird die gewünschte Funktionalität noch nicht zur Verfügung gestellt, sondern lediglich beschrieben.
• Soll sie Schnittstelle realisiert werden, muss eine Klasse das Interface implementieren:
® Erweiterung der class-Anweisung um eine implements-Klausel.
® Der Compiler sorgt dafür, dass alle im Interface geforderten Methoden definitionsgemäß implementiert werden.
® Zusätzlich "verleiht" er der Klasse einen neuen Datentyp, der ähnliche Eigenschaften wie eine echte Klasse hat.
26
BeispielefürdieImplementierungeinesInterface
public class FussballPlatz
implements Groesse {
public int laenge() {return 105000;}
public int hoehe() {return 0;}
public int breite() {return 70000;}
}
public int hoehe() {return 0;}
public int breite() {
int ret = 0;
if (format == 0) {ret = 841;}
else if (format == 1) {ret = 594;}
else if (format == 2) {ret = 420;}
else if (format == 3) {ret = 297;}
else if (format == 4) {ret = 210;}
//usw...
return ret;
}
}
public class PapierBlatt implements Groesse {
public int format;
//0=DIN A0, 1=DIN A1 etc.
public int laenge() {
int ret = 0;
if (format == 0) {ret = 1189;}
else if (format == 1) {ret = 841;}
else if (format == 2) {ret = 594;}
else if (format == 3) {ret = 420;}
else if (format == 4) {ret = 297;}
//usw...
return ret;
}
1a
2
1b
27
VerwendungvonInterfaces
o InterfacessindgenausoTypenwieKlassenundkönnenüberalldortverwendetwerden,woaucheineKlasse(alsTyp)verwendetwerdenkann:¤ als Typ einer Variablen,¤ alsTypeinesParameters,¤ alsRückgabetypeinerMethode,¤ ineinemTyp-TestodereinemTypeCast.
o ÜberdenInterface-TypsindnurdieMethodendesInterfacessichtbar.
o ObjekteeinerKlasse(odervoneinerihrerUnterklassen),dieeinInterfaceimplementiert,könnenüberallalskonkreterWertfüreineVariableodereinenParametervomInterface-Typeingesetztwerden.
28
ImplementierungvonInterfaces
o Die implements-Beziehung wird weitervererbt.o Klassen,dieeinInterfaceimplementieren,
¤ implementierenalleMethodendesInterfacesoder¤ implementierennureinenTeil derMethoden→müssendannselbst
abstraktsein.
29
Interfacesinder UML
«interface»FigurMitFläche
berechneFläche () : floatverdoppleFläche ()
Das Namensfeld wirddurch «interface» gekennzeichnet ("UML Stereotype")
Kreis
Die "implements"-Beziehungwird durch eine gestrichelte Linie
mit Vererbungspfeil gekennzeichnet
Test
Die "uses"-Beziehungwird durch eine gestrichelte Linie mit offenem Pfeil gekennzeichnet
30
VerwendenvonInterfaces- Beispiel
public static long grundflaeche(Groesse g) {
return (long)g.laenge() * g.breite();
}
public static void main(String[] args) {
//Zuerst erzeugen wir ein DIN A4-Blatt...
PapierBlatt blatt = new PapierBlatt();
blatt.format = 4;
//und dann einen Fußballplatz...
FussballPlatz platz = new FussballPlatz();
//Nun werden sie ausgegeben
System.out.println("Blatt: " + grundflaeche(blatt));
System.out.println("Platz: " + grundflaeche(platz));
}
Eine Interface-Variable ist kompatibel zu allen Objekten, deren Klassen dieses Interface implementieren.
31
DasInterfaceComparable
o Typische Anwendung von Interfaces: Eigenschaftenausdrücken, die auf Klassen aus unterschiedlichenKlassenhierarchien zutreffen können.
o Erkennungsmerkmal: Interfacename = (oft) substantiviertesEigenschaftswort.
o Bekanntes Beispiel (seit Version 1.2) in der Java-Klassenbibliothek:
Interface Comparable des Pakets java.lang:
public interface Comparable {public int compareTo(Object o);}
o Dieses Interface kann von Klassen implementiert werden,deren Objekte paarweise vergleichbar sind.
32
Comparable - Beispiel
public static void main(String[] args) {//Erzeugen eines String-ArraysComparable[] objects = new Comparable[4];
objects[0] = "STRINGS";objects[1] = "SIND";objects[2] = "PAARWEISE";objects[3] = "VERGLEICHBAR";
//Sortieren und AusgebenbubbleSort(objects);for (int i = 0; i < objects.length; ++i) {
System.out.println((String)objects[i]);}
} Beachte: Generizität (Typunabhängigkeit) der Lösung. Es spielt keine Rolle, welche Art von Objekten sortiert wird, solange alle das Interface Comparable implementieren, wie z.B. bei Strings.
Eigene Klassen müssen ihre eigene Implementierung von Comparable beisteuern.
33
Mehrfachimplementierung
o Esistmöglich(undgebräuchlich),dasseineKlassemehrereInterfacesimplementiert.
o SiemussdannzujedemInterfacealledarindefiniertenMethodenimplementieren.o MitjedemimplementiertenInterfacewirdsiezudemdadurchdefiniertenDatentyp
kompatibel.
public class Auto3 implements Groesse, Comparable {
public String name;
public int erstzulassung;
public int leistung;
. . .public int laenge() { // Implementierung zu IF Groesse } . . .
public int compareTo(Object o) { // Impl. zu IF Comparable
int ret = 0;
if (leistung < ((Auto3)o).leistung) { ret = -1;}
else if (leistung > ((Auto3)o).leistung) {ret = 1;}
return ret;
}
}
34
VererbungvonInterfaces
o EineKlassevererbt,außerdenAttributenundMethodenauchdieInterfaces,diesieimplementiert.public class Auto2 implements Groesse { . . . }
public class Auto4 extends Auto2 implements Comparable {
...public int compareTo(Object o) {
int ret = 0;
if (leistung < ((Auto4)o).leistung) {ret = -1;}else if (leistung > ((Auto4)o).leistung) {ret = 1;}
return ret;
} }
o Die Klasse Auto4 erbt von Auto2 auch das Interface Groesse bzw. dessen Implementierung. Zusätzlich implementiert die Klasse das Interface Comparable. Damit sind die Klassen Auto4 und Auto3 (s.o.) gleichwertig.
35
AbleitungvonInterfaces
o Interfacesselbstkönnenauchabgeleitetwerden.o DasabgeleiteteInterface(erbtähnlicheinerKlasse)alle
MethodendefinitionendesBasis-Interfaces.o EineimplementierendeKlassemussdannauchalle
MethodenvonallenübergeordnetenInterfacesimplementieren.
o DieVererbungshierarchiezwischenInterfacesstehtnebenderVererbungshierarchiederKlassen.
36
AbleitungvonInterfaces- Beispiel
interface EinDimensional {public int laenge();}
interface ZweiDimensional extends EinDimensional{public int breite();}
interface DreiDimensional extends ZweiDimensional{public int hoehe();}
interface VierDimensional extends DreiDimensional{public int lebensdauer();}
public class Mehrdimensional implements VierDimensional {
public int laenge() { return 0; }
public int breite() { return 0; }
public int hoehe() { return 0; }
public int lebensdauer() { return 0; }
}
37
WeitereAnwendungvonInterfaces
o ZentraleDefinitionvonKonstanten(gängigePraxisbisJava5)o ImplementierungvonFlagso NachbildungvonFunktionszeigern(sog.Callback-Funktionen)o Mehrfachvererbung
38
ZentraleDefinitionvonKonstanten
o NebenabstraktenMethodenkönnenInterfacesauchKonstanten(Membervariablen mitdenAttributenstatic undfinal)enthalten.
o WenneineKlasseeinInterfaceimplementiert,erbtsieauchalleKonstanten.
o Esistaucherlaubt,dasseinInterfaceausschließlichKonstantenenthält.o DieseEigenschaftkannnützlichsein,wenneinProgrammsehrviele
Konstantendefiniert.AnstattsieinihreneigenenKlassenzubelassenundbeijedemGebrauchmitKlasse.Name aufzurufen,könnteeineinzelnesInterfacedefiniertwerden,dasalleKonstantendefinitionen vereinigt.
o JedeKlasse,inderdieseKonstantenbenötigtwerden,mussdiesesInterfaceimplementieren.
Sollte nicht mehr verwendet werden: „Man implementiert kein Interface, das nur Konstanten enthält.“Besser: Konstantenklasseund statischer Import (wie bei MakeItSimple).
39
Interfaces:ImplementierungvonFlags
o EinigeInterfacesdefinierenwederMethodennochKonstanten.o SiestellenstattdesseneineArtFlag,alsoeinenlogischenSchalter
dar,derzurCompile- undLaufzeitabgefragtwerdenkann.o BeispieleausderKlassenbibliotheksinddieInterfacesjava.io.Serializable oderjava.lang.Cloneable.
o DasInterfaceCloneable isteinSchalterfürdieinderKlasseObject implementierteMethodeclone.
o ImplementierteineabgeleiteteKlassediesesInterfacenicht,sodeutetclone dasalsfehlendeFähigkeit(oderBereitschaft)derKlasse,eineObjektkopieherzustellen,undlöstbeimAufrufeineCloneNotSupported-Exception aus.
o ImplementiertdieabgeleiteteKlasseCloneable,erzeugteinAufrufvonclone eineelementweiseKopiedesaktuellenObjekts.
40
Objekt-Replikation
Replikation=KopieeinesexistierendenObjektsmitderselbenBelegungderDatenelemente.Esgibt2Möglichkeiten:o EinKonstruktor (copy-Konstruktor)nimmteinvorhandenesObjektals
Vorlage,erzeugteinneuesObjektundkopiertdieDatenelementedesaktuellenObjektsindasneue.
o AufrufderMethodeclone (ausderKlasseObject)→dasLaufzeitsystemlegtselbsteineKopiedesObjektsan.
o clone hatdenModifier protected →istnichtaufrufbar!o Willmanclone ausObject benutzen:
¤ MussindenKlassen,dieklonbare Exemplarehaben,clone überschriebenwerden.¤ Dortwirddannmitsuper.clone()dieMethodeclone vonObject aufgerufen.¤ DerAufrufvonsuper.clone()istnurdannzulässig,wenndieKlassedieSchnittstelle
Cloneable implementiert.Sonst→CloneNotSupportedException.
An anderer Stelle mehr!
41
NachbildungvonFunktionszeigern(Callbacks)
o FunktionszeigersindinJavanichtvorhandenen,könnenabermitHilfevonInterfacesnachgebildetwerden.
o Damitistesmöglich,eineFunktionalsArgumentanandereFunktionenzuübergeben.
o Dasistnützlich,wenndieKonfigurationsanforderungeneinerFunktiondiedurchdieÜbergabevonVariablengegebenenMöglichkeitenübersteigen.
o BeispielefürihreAnwendungsindetwaFunktionsplotteroderCallback-FunktionenbeiderProgrammierunggrafischerOberflächen.
42
NachbildungvonFunktionszeigern- Beispiel
class MathExp implements DoubleMethod {
public double compute(double value) {return Math.exp(value);}
}
class MathSqrt implements DoubleMethod { ... }
class Times2 implements DoubleMethod { ... }
class Sqr implements DoubleMethod { ... }
public class FctPointers {
public static void printTable(DoubleMethod meth) {
System.out.println("Wertetabelle " + meth.toString());
for (double x = 0.0; x <= 5.0; x += 1) {
System.out.println(" " + x + "->" + meth.compute(x));}
}
public static void main(String[] args) {
printTable(new MathExp());
printTable(new Times2());
}
}
public interface DoubleMethod {
public double compute (double value);
}
Dem Interface-Parameter können Objekte aller Klassen zugewiesen werden, die das Interface implementieren.
43
Interfacesund(abstrakte)Klassen-Gemeinsamkeiten
o WährendderDesignphaseeineskomplexenSoftwaresystems:häufigschwierig,sichfüreinevonbeidenVariantenzuentscheiden.
o ProInterfaces:größereFlexibilität durchdieMöglichkeit,inunterschiedlichenKlassenhierarchienverwendetzuwerden.
o ProKlasse:Möglichkeit,bereitsausformulierbareTeilederImplementation zurealisierenunddieFähigkeit,statischeBestandteileundKonstruktoren unterzubringen.
o KombinationderbeidenAnsätze:zunächstzurVerfügungstelleneinesInterfaces,dannVereinfachungseinerAnwendungdurchVerwendungeinerHilfsklasse.
44
Interfacesvs.AbstrakteKlasseBeispiel:NachträglicheÄnderungen
o AuchnachträglicheÄnderungenanSchnittstellensindnichteinfach:EinerabstraktenKlassekanneinekonkreteMethodemitgegebenwerden,waszukeinerQuellcodeanpassungfürUnterklassenführt.
o IsteineSchnittstelleodereineabstrakteKlassebesser,umfolgendeOperationzudeklarieren?
abstract class Time {
abstract long getTimeInMillis()
}
interface Time {
long getTimeInMillis();
}
45
Interfacesvs.AbstrakteKlasseBeispiel:NachträglicheÄnderungen
abstract class Timer {
abstract long getTimeInMillis();
long getTimeInSeconds() {
return getTimeInMillis() / 1000;
}
}
Wasistzutun,wennmaneineHilfsfunktiongetTimeInSeconds() einführenwill?
InSchnittstelleà alleimplementierendenKlassenmüssendieseImplementierungneueinführen.
InabstrakterOberklasseà einfachinderabstraktenKlasseeinfügen,keineÄnderungenderKlassen-Verwendernotwendig.
46
KombinationvonInterfaces
interface I1 { void f(); }
interface I2 { int f(int i); }
interface I3 { int f(); }
class C { public int f() { return 1; } }
class C2 implements I1, I2 {
public void f() {}
public int f(int i) { return 1; } // overloaded
}
class C3 extends C implements I2 {
public int f(int i) { return 1; } // overloaded
}
class C4 extends C implements I3 {
// Identical, no problem:
public int f() { return 1; }
}
class C5 extends C implements I1 {}
interface I4 extends I1, I3 {}
Die Verwendung desselben Methodennamens in verschiedenen Interfaces, die man evtl. kombinieren möchte, sorgt für schlecht lesbaren Code.
à Vermeiden !!!
Quelle: Eckel
47
VererbungvonInterfacesinterface Monster {
void menace();
}
interface DangerousMonster extends Monster {
void destroy();
}
interface Lethal {
void kill();
}
class DragonZilla implements DangerousMonster{
public void menace() {}
public void destroy() {}
}
interface Vampireextends DangerousMonster, Lethal {
void drinkBlood();
}
class VeryBadVampire implements Vampire {
public void menace() {}
public void destroy() {}
public void kill() {}
public void drinkBlood() {}
}
/*
public class HorrorShow {
static void u(Monster b) { b.menace(); }
static void v(DangerousMonster d) {
d.menace();
d.destroy();
}
static void w(Lethal l) { l.kill(); }
public static void main(String[] args) {
DangerousMonster barney = new DragonZilla();
u(barney);
v(barney);
Vampire vlad = new VeryBadVampire();
u(vlad);
v(vlad);
w(vlad);
}
}
[Quelle: Eckel]
48
Bemerkung:NachteilvonInterfaces
o InterfaceskönnennurKonstantenundabstrakteMethodenandieKlassenweitergeben,vondenensieimplementiertwerden.
o ImUnterschiedzuabstraktenKlassenkönnenalsokeine(überallverfügbaren)AttributeundkeineImplementierungweitergegebenwerden.
o DafüristoftDelegationnutzbar,manchmalauchAdapter-KlassenzusammenmitanonymenKlassen(diesewerdenwirimZusammenhangmitGUI-Programmierungnochkennenlernen).
49
KombinationvonInterfacesundabstraktenKlassen
o AdapterstelleneineBasisimplementierungeinesInterfaceszurVerfügung.
«interface»Interface
+ method1()+ method2()+ method3()
+ method4()+ method5()
AbstractInterface{abstract}
+ method1()+ method2()
+ method3()
+ method4()
+ method5()
InterfaceImplementation
+ method2()+ method4()
Die abstrakte Klasse implementiert Teile des Interface (Implementierungsskelett)
Hier müssen nur noch wenige Methoden implementiert werden
InterfaceAdapter
50
Interfacesvs.abstrakteKlassen
o WennmandieMöglichkeithabenwillinmehralseinenBasistyp zuverallgemeinern(upcast)à Interface.
o WennderClient-ProgrammiererkeinObjekterzeugenkönnensollà InterfaceoderabstrakteKlasse.
o Wennmöglich,d.h.wenneineKlasseohneMethoden-DefinitionenoderMember-Variablenvereinbartwerdenkann,dannsolltemaneinInterfacederabstraktenKlassevorziehen.
o AbstrakteKlassenwerdeneingesetzt,umgemeinsameMethodeninderVererbungshierchieander„richtigen“Stellezuplatzieren.
51
MotivationfürdieJava8ErweiterungenvonInterfaces
o InterfaceskönnennachderVeröffentlichungnichtmehrgeändertwerden.
o Warum?JedeÄnderungdesInterfaces (d.h.dasHinzufügenvonMethoden)à alleVerwender(Clients)müssenneuübersetztwerden.⇒ SehrvielSorgfaltindenEntwurfderSchnittstellen
stecken.⇒ Trotzdemkommtesnochhäufigvor,dassmanein
Interfacetrotzdemspäteranpassenmuss.o BisherigeLösung:AnlegeneinesneuenInterface,dasvom
ursprünglichenerbtundeserweitert.
52
ErweiterungeninJava8
Jetztkönnenauch¤ Default-Methoden¤ StatischeMethoden
imInterfaceselbstimplementiertwerden.
⇒ AufhebungeinigerEinschränkungenvonInterfaces.⇒ MehrFlexibilitätfürdenEntwickler.
defender methods
53
StatischeMethodenimInterface
o Statische Methoden in Interfaces entsprechen i.w. statischenMethoden in Klassen:¤ werden nicht “vererbt”.¤ müssen immer über ihr definierendes Interface in der FormInterfaceName.staticMethod(…) aufgerufen werden.
54
Default-MethodenimInterface
o Bieten die Möglichkeit, nachträglich im Interface Methodenhinzuzufügen ohne existierenden Code von Klassen, die einso erweitertes Interface implementieren, verändern zumüssen (® Flexibilität).
o Stehen in allen implementierenden Klassen zur Verfügung,werden also vererbt und können auch in implementierendenKlassen überschrieben werden (® Aufhebung von Einschrän-kungen).
55
Auswirkungvondefault Methoden
WennInterfacevoneinemInterfacemitDefault-Methodenerbt,kannes
o dieMethodeignorieren→Methodewird(normal)vererbt
o dieMethode(natürlichohneImplementierung)ohnedefault angeben→Methodewird(normale)abstrakteMethode.
o dieMethodemitdefault angeben→Methodewirdüberschrieben.
o abstrakteMethodedurchdefault-Methodeersetzen→ImplementierendeKlassemusssienichtmehr
implementieren.
56
MehrfachvererbungundInterfacesmitDefault-Methoden
o EineKlassekannmehralseinInterfaceimplementierenàMehrfachvererbungvonDefault-Methodenmöglich.
⇒ Daskann(genauwieinanderenSprachenmitMehrfachver-erbung)zuKonfliktenführen.
¤ Haben zwei Interfaces IA und IB je eine Default-Methode mitderselben Signatur à muss in einer Klasse C, die beide Interfaces(direkt oder indirekt) implementiert die Default-Methodeüberschrieben werden.
¤ Alternativ kann die Default-Methode in der Klasse C auch als abstraktdeklariert werden (C ist dann auch abstrakt) Die Konfliktauflösung wirdden Subklassen von C überlassen.
57
Mehrfachvererbung - Konflikt:Beispiel
Compilerfehler: Duplicate default methods named methode withthe parameters () and () are inherited from the types I1a and I1
Überschreiben der mehrdeutigen Default-Methode
58
Mehrfachvererbung - Konflikt:Beispiel
Compilerfehler: Duplicate default methods named methode withthe parameters () and () are inherited from the types I1a and I1
Überschreiben der mehrdeutigen Default-Methode mit Verwendung (Aufruf) der Default-Methoden der beiden Interfaces
59
Mehrfachvererbung - Konflikt:Beispiel
Compilerfehler: Duplicate default methods named methode withthe parameters () and () are inherited from the types I1a and I1
Mehrdeutigen Default-Methode als abstrakte Methode überschreiben.
60
KonfliktDefault-MethodemitKlassenmethode
BeieinemKonflikthabendieMethodeneinerKlasseVorrangvordenDefault-MethodenderInterfaces.
61
InterfacesundstatischeMethoden
o StatischeMethodeninInterfacessindidentischmitdenstatischenMethodenvonKlassen.
o Motivation:¤ WennmanHilfsfunktionenanbietenmöchte,dieengmitdemInterface
verbundensind.¤ BishermusstemanimmereineKlasseangeben,diediestatischen
Methodenenthielt.JetztkönnendiesedirektimInterfaceangegebenwerden.