1 Abstrakte Klassen, finale Klassen und Interfaces

Transcription

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, heißt
ebenfalls abstrakt.
•
Eine abstrakte Klasse kann nicht instanziiert werden.
•
Mit abstrakten Klassen können wir Unterklassen mit
verschiedenen Implementierungen der gleichen
Objekt-Methoden zusammenfassen.
1
Beispiel:
Implementierung einer Mitarbeiterdatenbank
abstract class Mitarbeiter {
private int persnr;
String name;
Date eintritt;
public Mitarbeiter() {}
public int personalNummer(){return persnr};
public abstract double monatsBrutto();
}
2
•
Die Unterklassen von Mitarbeiter repräsentieren die
konkreten Mitarbeitertypen, die die Firma hat.
•
Allen Unterklassen gemeinsam ist eine Objekt-Methode
monatsBrutto() – immer mit einer anderen Implementierung
•
Die statischen Variablen der Oberklasse stehen sämtlichen
Unterklassen zur Verfügung.
3
•
Eine abstrakte Objekt-Methode wird durch das Schlüsselwort
abstract gekennzeichnet.
•
Eine Klasse, die eine abstrakte Methode enthält, muss selbst
ebenfalls als abstract gekennzeichnet sein.
•
Für die abstrakte Methode muss der vollständige Kopf
angegeben werden – inklusive den Parameter-Typen und den
(möglicherweise) geworfenen Exceptions.
•
Die konkrete Default-Implementierung für int
personalNummer() kann von anderen Klassen überschrieben
werden.
•
Die Methode monatsBrutto() soll den Monatslohn eines
Mitarbeitertyps berechnen zurückliefern.
4
Beispiel für unterschiedliche Mitarbeitertypen:
class Arbeiter extends Mitarbeiter {
double stundenlohn;
double anzahlstunden;
double ueberstundenzuschlag;
double anzahlueberstunden;
double schichtzulage;
public double monatsBrutto() {
return stundenlohn*anzahlstunden+
ueberstundenzuschlag*anzahlueberstunden+
schichtzulage;
}
}
5
class Angestellter extends Mitarbeiter {
double grundgehalt;
double ortszuschlag;
double zulage;
public double monatsBrutto() {
return grundgehalt+
ortszuschlag+
zulage;
}
}
6
class Manager extends Mitarbeiter {
double fixgehalt;
double provision1;
double provision2;
double umsatz1;
double umsatz2;
public double monatsBrutto() {
return fixgehalt+
umsatz1*provision1/100+
umsatz2*provision2/100;
}
}
7
public class Example{
private static final int ANZ_MA = 100;
private static Mitarbeiter ma[];
private static double bruttosumme;
public static void main(String args[]) {
ma = new Mitarbeiter[ANZ_MA];
//Mitarbeiter-Array füllen, z.B.
//ma[0] = new Manager();
//ma[1] = new Arbeiter();
//ma[2] = new Angestellter();
//...
8
//Bruttosumme berechnen
bruttosumme = 0.0;
for (int i=0; i<ma.length; ++i) {
bruttosumme += ma[i].monatsBrutto();
}
//Welche konkrete Methode jeweils aufgerufen wird,
//hängt von der konkreten Klasse des jeweiligen Objekts
//ab, d.h. entscheidet sich erst zur Laufzeit
//Dynamische Binding oder Dynamic Method Lookup
write("Bruttosumme = "+bruttosumme);
}
}
9
Der final-Modifier
•
Wird eine Klasse als final deklariert, bedeutet das, dass von der
Klasse keine Klasse abgeleitet werden kann.
•
Wird eine Variable als final deklariert, bedeutet das, dass die
Variable konstant ist.
•
Wird eine Methode als final deklariert, bedeutet das, dass die
Methode in Unterklassen nicht überschrieben werden kann.
Der Zweck von final Deklarationen:
•
Sicherheit: Niemand soll in der Lage sein, Subklassen und neue
oder andere Instanzen zu erstellen.
•
Effizienz: Es können Compileroptimierungen durchgeführt
werden, da sich Instanzen nur in einer Klasse (nicht in
Subklassen) befinden.
10
Beispiel
public
void
}
public
void
}
final class Ober {
sicher() { }
class Unter extends Ober { // Compilerfehler!
sicher() { }
class Ober {
final void sicher() { }
}
class Unter extends Ober {
void sicher() { } // Compilerfehler!
}
11
Leider (zum Glück?) lässt sich nicht die ganze Welt hierarchisch
organisieren
12
Beispiel:
Comparable
AddSubMulDiv
Rational
Complex
AddSubMulDiv
= Objekte mit Operationen add(), sub(),
mul(), und div()
Comparable
= Objekte, die eine compareTo()-Operation besitzen.
13
•
Mehrere direkte Oberklassen einer Klasse führen zu
konzeptuellen Problemen:
•
Auf welche Klasse bezieht sich super ?
•
Welche Objekt-Methode meth() ist gemeint, wenn wenn
mehrere Oberklassen meth() implementieren ?
meth() A
meth() B
C
14
•
Kein Problem entsteht, wenn die Objekt-Methode meth() in
allen Oberklassen abstrakt ist
•
oder zumindest nur in maximal einer Oberklasse eine
Implementierung besitzt
Ganz allgemein ist das Problem also, dass Klassen nur eine
Basisklasse in einer Vererbungshierarchie haben dürfen. Um dieses
Problem zu umgehen, kann man in Schnittstellendefinitionen die zu
implementierenden Methoden und Datenelemente bestimmen.
15
•
Kein Problem entsteht, wenn die Objekt-Methode meth() in
allen Oberklassen abstrakt ist
•
oder zumindest nur in maximal einer Oberklasse eine
Implementierung besitzt
Ganz allgemein ist das Problem also, dass Klassen nur eine
Basisklasse in einer Vererbungshierarchie haben dürfen. Um dieses
Problem zu umgehen, kann man in Schnittstellendefinitionen die zu
implementierenden Methoden und Datenelemente bestimmen.
16
Eine Schnittstelle (Interface) kann aufgefasst werden als eine
abstrakte Klasse, wobei:
•
alle Objekt-Methoden abstrakt sind, also lediglich
Methodendeklarationen (die Signaturen: Methodenname,
Namen, Anzahl, Reihenfolge und Typen der Parameter, Typ
des Rückgabewertes) ohne einen Anweisungsrumpf enthalten;
•
es keine Klassen-Methoden gibt;
•
alle Variablen Konstanten sind;
•
kein Konstruktor definiert werden darf.
17
Was bringen Interfaces?
•
Zuerst einmal keine Einsparungen bei der Programmierung!
•
Über Schnittstellen lässt sich allerdings eine Sicht auf ein Objekt
beschreiben. Jede Schnittstelle definiert eine Sicht (ein Rolle),
und implementiert eine Klasse mehrere Schnittstellen, dann
können die Instanzen in verschiedenen Rollen auftreten.
•
Schnittstellen repräsentieren eine Garantie bezüglich der in
einer Klasse vorhandenen Methoden. Sie geben an, dass alle
Objekte, die diese Schnittstelle besitzen, gleich behandelt
werden können.
•
Schnittstellen werden verwendet, um Kompatibilitäten
zwischen Klassen zu definieren, die nicht voneinander erben.
18
Beispiel:
public interface Comparable {
int compareTo(Object x);
}
•
Object ist die gemeinsame Oberklasse aller Klassen.
•
Methoden in Interfaces sind automatisch Objekt-Methoden und
public.
•
Evt. vorkommende Konstanten sind automatisch public
static.
19
Beispiel (Forts.):
public class Rational extends AddSubMulDiv
implements Comparable {
private int zaehler, nenner;
public int compareTo(Object cmp) {
Rational fraction = (Rational) cmp;
long left = zaehler * fraction.nenner;
long right = nenner * fraction.zaehler;
if (left == right) return 0;
else if (left < right) return -1;
else return 1;
} // end of compareTo
...
}
// end of class Rational
20
•
class A extends B implements B1, B2,...,Bk {...}
gibt an,
dass die Klasse A als Oberklasse B hat und zusätzlich die
Interfaces B1, B2,...,Bk unterstützt, d.h. passende
Objekt-Methoden zur Verfügung stellt.
•
Java gestattet maximal eine Oberklasse, aber beliebig viele
implementierte Interfaces.
•
Die Konstanten des Interface können in implementierenden
Klassen direkt benutzt werden.
•
Interfaces können als Typen für formale Parameter, Variablen
oder Rückgabewerte benutzt werden.
•
Darin abgelegte Objekte sind dann stets aus einer
implementierenden Klasse.
•
Expliziter Cast in eine solche Klasse ist möglich
21
•
Interfaces können andere Interfaces erweitern oder gar mehrere
andere Interfaces zusammenfassen.
•
Erweiternde Interfaces können Konstanten umdefinieren...
•
Kommt eine Konstante gleichen Namens const in
verschiedenen implementierten Interfaces A und B vor, kann
man sie durch A.const und B.const unterscheiden
Beispiel (Forts.):
public interface Countable extends Comparable, Cloneable {
Countable next();
Countable prev();
int number();
}
22
•
Das Interface Countable umfasst die (beiden vordefinierten)
Interfaces Comparable und Cloneable.
•
Das vordefinierte Interface Cloneable verlangt eine
Objekt-Methode public Object clone() die eine Kopie
des Objekts anlegt.
•
Eine Klasse, die Countable implementiert, muss über die
Objekt-Methoden compareTo(), clone(), next(), prev()
und number() verfügen.
23
Übersicht:
Object
Interfaces
Cloneable
Countable
Comparable
Rational
AddSubMulDiv
Complex
Klassen-Hierarchie
24