einführung in die objektorientierung teil 4 interfaces, polymorphie … · 2016. 6. 27. · •...
Post on 01-Oct-2020
0 Views
Preview:
TRANSCRIPT
Name: Patrick Förster, Michael Hasseler
Programmieren in Java
Einführung in die Objektorientierung Teil 4
Interfaces, Polymorphie und innere Klassen
Name: Patrick Förster, Michael Hasseler
• Vererbung repräsentiert eine „ist ein“ Beziehung zwischen Klassen
• Eine Handtasche ist eine Ware
• Eine Jacke ist eine Ware
• Ein Schuhpaar ist eine Ware
Vererbung im Klassendiagramm (Wiederholung)
2 Programmieren in Java
Schuhpaar
groesse: int
Ware
farbe: String
marke: String
neupreis: float
warennummer: int
zustand: Zustand
Handtasche
breite: float
hoehe: float
Vererbung
Jacke
groesse: Groesse
Object
Name: Patrick Förster, Michael Hasseler
• Das Schlüsselwort zu Deklaration von Vererbung ist extends
• Java kennt nur einfache Vererbung, d.h. eine Klasse kann maximal von einer anderen
Klasse erben • Die Hierarchietiefe ist allerdings beliebig, d.h. die Elternklasse (oben Ware) kann wieder
von einer anderen Klasse erben
Vererbung in Java I (Wiederholung)
3 Programmieren in Java
public class {
}
BEZEICHNER
…
extends KLASSEN-BEZEICHNER
public class Handtasche extends Ware {
private float breite;
private float hoehe;
…
}
public class Ware {
private float neupreis;
…
}
public class Schuhpaar extends Ware {
…
}
Name: Patrick Förster, Michael Hasseler
• Sprachgebrauch:
• Elternklasse: Klasse von der geerbt wird
• Kindklasse: Alle von einer Elternklasse erbenden Klassen
• Eine Kindklasse erbt:
• Alle Attribute der Elternklasse
• Alle Methoden der Elternklasse
• Alle Konstruktoren der Elternklasse
• Zugriff auf Elemente (Attribut, Methode, Konstruktor) zur Laufzeit:
• Ist das Element in der Klasse der aktuellen Instanz definiert?
• Falls nein: Ist das Element ein der Elternklasse definiert?
• Falls nein: Hat die Elternklasse eine Elternklasse?
• Falls ja: Die Hierarchie durchlaufen, bis das Element gefunden wurde
• Ansonsten: Compiler-Fehler
Vererbung in Java II (Wiederholung)
4 Programmieren in Java
Name: Patrick Förster, Michael Hasseler
• Es gibt vier Sichtbarkeitsmodifiktoren für Attribute und Methoden • public: Zugriff von „überall“
• protected: Zugriff innerhalb des Packages und bei Vererbung
• [keine Angabe]: Zugriff innerhalb des Packages („package private“)
• private: Zugriff nur innerhalb der eigenen Klasse/Instanz
• Das Attribut neupreis ist nur innerhalb von Ware verwendbar
• Es gibt zwei Sichtbarkeitsmodifikatoren für Klassen: • public: Zugriff von „überall“
• [keine Angabe]: Zugriff innerhalb des Packages („package private“)
• Insbesondere: Nur die mit dem Dateinamen übereinstimmende Klasse kann public
sein
Sichtbarkeit (Wiederholung)
5 Programmieren in Java
public class Ware {
private float neupreis;
…
}
Name: Patrick Förster, Michael Hasseler
• Klassen können mit abstract als abstrakt definiert werden
• Ist eine Klasse abstrakt, so kann keine Instanz der Klasse erzeugt werden
• Ebenso können Methoden als abstract definiert werden
• Eine abstrakte Methode hat keinen Methodenrumpf (Implementierung)
• Lediglich die Signatur wird angegeben
• Existiert innerhalb einer Klasse mindestens eine abstrakte Methode, so muss auch die Klasse abstract sein
• Alle erbenden Klassen müssen entweder die Methode implementieren oder sind selbst wieder abstract
Abstrakte Klassen/Methoden (Wiederholung)
6 Programmieren in Java
public abstract class Ware {
}
SICHTBARKEIT abstract KLASSEN-BEZEICHNER {
}
class
optional
SICHTBARKEIT RÜCKGABETYP ( DATENTYP BEZEICHNER PARAM-
BEZEICHNER
, … abstract
public abstract float getWarenwert();
);
Name: Patrick Förster, Michael Hasseler
• Ein Interface (Schnittstelle) ist eine abstrakte Klasse, in der alle Methoden • public sind (per default, eine Sichtbarkeit muss nicht angegeben werden)
• abstrakt sind (per default, abstract muss nicht angegeben werden)
• Eine Klasse „implementiert“ ein Interface • Die Beziehung wird nicht per extends sondern mit implements angegeben
Interfaces
7 Programmieren in Java
public interface IForm {
public double getFlaeche();
public double getUmfang();
}
SICHTBARKEIT interface BEZEICHNER {
}
RÜCKGABETYP ( ); DATENTYP BEZEICHNER PARAM-
BEZEICHNER
, …
public class {
}
BEZEICHNER
…
implements INTERFACE-BEZEICHNER
Name: Patrick Förster, Michael Hasseler
• Innerhalb eines Interfaces können keine Instanz-Attribute definiert werden
• Klassenattribute sind möglich
• Eine implementierende Klasse muss entweder alle im Interface angegebenen Methoden definieren oder als abstract deklariert werden
• Eine Klasse kann beliebig viele Interfaces implementieren (Komma als Trennzeichen)
• Dadurch gewinnt man eine Art „Pseudo-Mehrfachvererbung“
• Es können Variablen vom Typ eines Interfaces definiert werden:
Interfaces (II)
8 Programmieren in Java
public abstract class Form implements IForm {
…
}
IForm form = new Kreis(5);
System.out.print(form);
public class Kreis extends Form {
private double radius
public Kreis(double radius){
this.radius = radius;
}
…
}
Name: Patrick Förster, Michael Hasseler
Trennung von Schnittstelle und Implementierung
• Allgemeines Design-Prinzip: „Programmiere gegen Schnittstellen, nicht gegen
Implementierungen.“ (Quelle: http://openbook.galileocomputing.de/oop/oop_kapitel_03_005.htm)
• Trennung ermöglicht ein einfacheres Austauschen der Implementierungen
• Ermöglicht ein Aufteilen in mehrere Arbeitspakete, die von verschiedenen
Personen parallel bearbeitet werden können.
• Hierfür werden im Vorfeld die Schnittstellen definiert
9 Objektorientierte Programmierung
Name: Patrick Förster, Michael Hasseler
• Interface IForm stellt der Verbindungsstück zwischen der Kiste und den Formen dar
• Klasse Kiste kennt nur das Interface IForm
• Ein Arbeitspaket könnte die Implementierung der Kiste sein und pro geometrischer
Figur ein weiteres Arbeitspaket
Klassendiagram mit Interface
10 Programmieren in Java
Quadrat
laenge: double
Quadrat(laenge: double)
getFlaeche(): double
getUmfang(): double
toString(): String
Form
PI: double
gerundet(): double
toString(): String
Kreis
radius: double
Kreis(radius: double)
getFlaeche(): double
getUmfang(): double
toString(): String
Kiste
formen: IForm
index: int
Kiste(anzahl: int)
formenAuflisten(): String
hinzufuegen(form IForm)
getGroessteFlaeche(): IForm
getKleinsteFlaeche(): IForm
toString(): String
Vererbung
Aggregation
<<interface>>
IForm
getFlaeche(): double
getUmfang(): double
Name: Patrick Förster, Michael Hasseler
Schnittstellen und abstrakte Klassen
• Gegenüberstellung von Unterschieden bei Interfaces und abstrakten Klassen:
11 Objektorientierte Programmierung
Schnittstelle Abstrakte Klasse
mögliche
Elemente
• Konstanten
• Methodensignaturen
ohne Rumpf
• Konstanten
• Variablen
• Methodensignaturen (mit
oder ohne Rumpf)
Regeln für
Klassen
Kann mehrere
Schnittstellen
implementieren
Kann maximal eine
Elternklasse haben
Name: Patrick Förster, Michael Hasseler
Polymorphie
• Polymorphie (Vielgestaltigkeit) ist eine wichtige Eigenschaft der OOP
• Polymorphie von Objekten gibt es nur bei Vererbungshierarchien
• Objekttyp einer Subklasse kann mit Objekttyp einer Basisklasse ausgetauscht
werden, wenn die Basisklasse nur erweitert wird und nur der Basisklasse
bekannte Elemente verwendet werden
• Überschriebene Methoden in der Subklasse müssen identisch zur ihrer
Basisklassenmethode aufrufbar sein
• Einsatz von Polymorphie für flexiblere Programme
12 Objektorientierte Programmierung
public static void main(String[] args) {
Ware ware;
ware = new Handtasche(…);
System.out.println(ware); // Handtasche:…
ware = new Schuhpaar(…);
System.out.println(ware); // Schuhpaar:…
}
Name: Patrick Förster, Michael Hasseler
• Die getFlaeche()-Methode ist den Zugriffsrechten entsprechend aufrufbar
• Demnach auch von der definierenden Klasse selbst
• Warum compiliert dies? • Da Form abstract ist kann es keine Instanz der Klasse Form geben
• toString kann nur von Instanzen aufgerufen werden
• D.h. es existiert eine Klasse in der Hierarchie des aufrufenden Objektes, die getFlaeche implementiert
• Welche Klasse dies ist, steht erst zur Laufzeit fest
• Dieses Verhalten nennt sich „spätes Binden“ (auch: „dynamisches Binden“)
• Abstrakte Methoden werden daher als „polymorph“ bezeichnet
Polymorphie
13 Programmieren in Java
public abstract class Form {
public abstract double getFlaeche();
@Override
public String toString() {
return … + "-> Fläche: " + this.getFlaeche() + …;
}
}
Name: Patrick Förster, Michael Hasseler
Geschachtelte Klassen
• Jackengröße über eine Enum-Klasse abgebildet
• Enum-Klassen können in einer eigenen Java-Datei abgelegt werden • Groesse-Enum existiert nur im direkten Zusammenhang mit der Klasse Jacke
• Um eine solche Abhängigkeit abzubilden bietet Java die Möglichkeit Klassen/Interfaces
innerhalb von Klassen/Interfaces zu definieren
14 Programmieren in Java
MODIFIKATOREN KLASSEN-BEZEICHNER { class|enum
}
…
MODIFIKATOREN
}
…
KLASSEN-BEZEICHNER { class|enum
public class Jacke extends Ware {
public enum Groesse {
S, M, L, XL, XXL,
};
…
}
Name: Patrick Förster, Michael Hasseler
Innere Klassen
• Innere Klasse wird in einer anderen Klasse definiert
• Beispiel:
• Schuhpaar ist die äußere Klasse und Schuh als innere Klasse darin geschachtelt
• Schuh wird nur im Schuhpaar verwendet und kann darin gekapselt werden und ist nach
außen nicht mehr sichtbar
15 Programmieren in Java
public class Schuhpaar {
…
public class Schuh {
private String farbe;
private int groesse;
…
}
}
Name: Patrick Förster, Michael Hasseler
Innere Klassen
• Der Zugriff auf innere Klassen erfolgt analog zu Klassenattributen über den
umschließenden Klassennamen
• Nur bei inneren Klassen kann der Modifikator static genutzt werden:
• Innerhalb eines Interfaces sind alle inneren Klassen automatisch static
• Geeignete Sichtbarkeit vorausgesetzt können von außen nur Instanzen von statischen
inneren Klassen erzeugt werden:
16 Programmieren in Java
Jacke.Groesse groesse = Jacke.Groesse.XL;
public class Schuhpaar {
…
public static class Schuh {
private String farbe;
private int groesse;
…
}
}
public class Schuhpaar {
…
public class Schuh {
private String farbe;
private int groesse;
…
}
}
Schuhpaar.Schuh schuh = new Schuhpaar.Schuh(…);
Schuhpaar.Schuh schuh = new Schuhpaar.Schuh(…); // Schuh nicht statisch
// Schuh statisch
Name: Patrick Förster, Michael Hasseler
• Java bietet die Möglichkeit anonyme Klassen zu definieren
• D.h. Klassen, für die kein Name vergeben wird
• Da diese Klassen allerdings keinen Namen haben, kann man sie nicht wie gewohnt über class definieren
• Definition findet quasi „ad hoc“ mit der Initialisierung einer Instanz statt
• Erweiterung einer bestehenden Klasse oder die Implementierung eines Interfaces
• Anonyme Klassen sind nicht statische innere Klassen
• Zugriff innerhalb der Implementierung auf alle Attribute der umschließenden Klasse
• Können innerhalb einer Methode definiert werden:
• Insbesondere können so Parameter an die Klasse übergeben werden
• Allerdings müssen die Parameter dafür als final deklariert werden
Anonyme innere Klassen
17 Programmieren in Java
IForm form = new Kreis(5) {
@Override public String toString() { return "[" + super.toString() + "]" }
};
System.out.print(form);
Name: Patrick Förster, Michael Hasseler
Zusammenfassung
• Wozu dienen Interfaces?
• Was unterscheidet ein Interface von einer abstrakten Klasse?
• Was versteht man unter Polymorphie in der OOP bei Objekten?
• Was versteht man unter „spätes Binden“ bzw. „dynamisches Binden“?
18 Programmieren in Java
Name: Patrick Förster, Michael Hasseler
Aufgabe
• Aufgabe 1a:
• Kopieren Sie das Netbeans-Projekt zur 9. Vorlesung mit dem Paketnamen de.wwu.ziv.vorlesungen.java.vorlesung9.aufgabe und der Klasse
Main an unter dem Projektnamen z. B. vl9_loesung.
• Erstellen Sie die Klasse Kreisring, die im Unterpaket formen liegt
• von der Klasse Form ableitet und das Interface IForm wie folgt
ausimplementiert:
• Die Klasse enthält die Attribute radius_a und radius_i vom Typ double.
• Der Konstruktor Kreisring(double radius_a, double
radius_i)setzt die Attribute radius_a und radius_i.
• Implementieren Sie die Methode getFlaeche mit A = Pi * ((radius_a)² -
(radius_i)²) und getUmfang mit U = 2 * Pi * (radius_a + radius_i).
• Überschreiben Sie die toString-Methode, sodass die Attribute der Klasse
Kreisring ausgegeben werden, wobei die toString-Methode der Oberklasse
wiederverwendet werden soll.
19 Programmieren in Java
Name: Patrick Förster, Michael Hasseler
Aufgabe
• Aufgabe 2:
• Erweitern Sie die Klasse Kiste um die Methoden getKleinstenUmfang und
getGroesstenUmfang.
• Erweitern Sie die Klasse Main analog zu den Ausgaben zu der größten und kleinsten
Fläche, sodass nun auch der kleinste und größte Umfang der Formen ermittelt wird.
• Instanziieren Sie in der Main-Klasse neben den Objekten aus der Vorlesung 9 zwei
Kreisringe, sodass diese mit der folgenden Konsolenausgabe übereinstimmt.
20 Programmieren in Java
Name: Patrick Förster, Michael Hasseler
Anhang: ZIVinteraktiv-Abstimmung
• QR-Code zur anonymen Abstimmung:
• https://www.uni-muenster.de/ZIV/anw/zivinteraktiv/abstimmung.php?code=571dedcd
21
top related