Beruflich Dokumente
Kultur Dokumente
Objektorientierung
Seite 1
Th Letschert
Seite 2
Nach dem Vorbild der Ingenieurwissenschaften (speziell der Elektrotechnik) wird komplexe Software in Module aufgeteilt. Fortschritt in der Softwaretechnik: Antwort auf die Frage: Was ist ein Software-Modul?
Begriff Modul
Ursprnglich Maeinheit / Gre standardisierter Bauteile von Gebuden spter Bezeichnung dieser Bauteile selbst 1950er: Bezeichnung standardisierter Bauteile in der Elektronik
Vorbild Bautechnik
1970er: bernahme der Idee und des Begriffs standardisierter Bauteile in die Informatik
Vorbild: Elektrotechnik/Elektronik / Einsatz: Betriebssystementwicklung (sehr groe Programme)
2000er: bernahme der Idee und des Begriffs standardisierter Bauteile in die hhere Ausbildung
Seite 3
Identischen Programmcode wiederverwenden Wiederverwendbarer Programmcode mit Parametern (Eingangswerten) Lokale Variablen, lokalem Algorithmus Ergebnis (Rckgabewert)
Funktionen / Prozeduren
Seite 4
Schnittstelle
Von auen zugreifbarer Teil der Funktionalitt zur Verfgung stellt
Implementierung
Interner Mechanismus der die Funktionalitt realisiert
Der Schnittstellen-Anteil soll so gro wie ntig sein. Der Implementierungsanteil soll so gro wie mglich sein. Ein Modul soll mglichst viel zu seinem Geheimnis machen.
Anwender: ist froh ber alles was er nicht wissen muss, wenn er das Bauteil verwenden will.
Seite 5
Entwickler: ist froh ber alles, auf das der Anwender nicht zugreifen kann: es kann ohne Rcksprache ersetzt werden.
Modularisierung und das Geheimnisprinzip Geheimnisprinzip: Schnittstelle (ffentlich) und Implementierung (privat)
sind bei allen Software-Komponenten stets explizit und klar erkennbar zu trennen !
Seite 6
Das Geheimnisprinzip
sorgt fr minimale Schnittstellen und so fr
ImplemenImplementierung tierung
Seite 7
Seite 8
Th Letschert
/* Schnittstelle * Sortiere eine Liste * Eingabe l: Liste vergleichbarer Daten * Ergebnis: Liste in sortierter Form, aufsteigende Reihenfolge */ void sort(List<Integer> l) { Collections.sort(l); }
Implementierung
Seite 9
Modul Telefonbuch
static int suche(String name) { for (int i=0; i<=letzterIndex; i++) { if (name == alleNamen[i]) { return alleNr[i]; } } return -1; } TelfonBuch.eintrage('Hugo', 4711) TelefonBuch.eintrage('Karla', 8150)
Modularisierung mit Klassen: Modularer Entwurf Public und Private: Schnittstelle / Implementierung trennen
class Telefonbuch { private static String[] alleNamen = new String[100]; private static int[] alleNr = new int[100]; private static int letzterIndex = -1; public static void eintrage(String name, int nr) { letzterIndex = letzterIndex+1; alleNamen[letzterIndex] = name; alleNr[letzterIndex] = nr; } public static int suche(String name) { for (int i=0; i<=letzterIndex; i++) { if (name == alleNamen[i]) { return alleNr[i]; } } return -1; } }
Modul Telefonbuch als Klasse mit Schnittstelle / Implementierung klar getrennt Compiler berwacht die Trennung!
TelfonBuch.eintrage('Hugo', 4711) TelefonBuch.eintrage('Karla', 8150) println TelfonBuch.suche('Hugo') println TelfonBuch.suche('Karla') TelfonBuch.letzterIndex = 100;
Seite 13
Seite 14
Daten
Die Daten der Vektoren (x-, y-Koordinate) werden jeweils durch eine Liste dargestellt.
a = new int[]{3,4}; b = new int[]{2,3};
a = 3,4
b = 2,3
Operationen
Die Vektoren-Operationen werden als Funktionen realisiert.
public static int[] vektorAdd(int[] x, int[] y) { return new int[]{x[0] + y[0], x[1] + y[1]}; } public static int[] vektorSub(int[] x, int[] y) { return new int[]{x[0] - y[0], x[1] - y[1]}; } public static int[] vektorSkalarMult(int s, int[] x) { return new int[]{s * x[0], s * x[1]}; }
Seite 15
Schnittstelle
int[] vektorAdd(int[] x, int[] y) { new int[]{x[0] + y[0], x[1] + y[1]}; int[] vektorSub(int[] x, int[] y) { new int[]{x[0] - y[0], x[1] - y[1]}; int[] vektorSkalarMult(int s, int[] x) { new int[]{s * x[0], s * x[1]};
Implementierung
int[] a = {3, 4}; int[] b = {2, 3}; System.out.println(Arrays.toString(Vektor.vektorAdd(a, b))); System.out.println(Arrays.toString(Vektor.vektorSub(a, b))); System.out.println(Arrays.toString(Vektor.vektorSkalarMult(3, a)));
Seite 16
Schnittstelle
int[] vektorAdd(int[] x, int[] y) { new int[]{x[0] + y[0], x[1] + y[1]}; int[] vektorSub(int[] x, int[] y) { new int[]{x[0] - y[0], x[1] - y[1]}; int[] vektorSkalarMult(int s, int[] x) { new int[]{s * x[0], s * x[1]};
Implementierung
int[] a = {3, 4}; int[] b = {2, 3}; System.out.println(Arrays.toString(Vektor.vektorAdd(a, b))); System.out.println(Arrays.toString(Vektor.vektorSub(a, b))); System.out.println(Arrays.toString(Vektor.vektorSkalarMult(3, a)));
Seite 17
Modularisierung mit Klassen: Modularer Entwurf Problematik des modularen Ansatzes im Fall der Vektoren Mangelhafte Kapselung
Wissen ber die Implementierung (speziell die Art der Speicherung in Listen) ist verstreut auf Vektor-Code (Funktionen: VektorAdd, ) und Anwendungscode (Anlegen von Vektoren) Problem Kopplung: Beides kann nur gemeinsam gendert werden Die Anwendung bentigt zu viel Wissen ber die Implementierung Schnittstelle und Implementierung sind nicht klar getrennt Konsequenz aufwndige Wartung aufwndige Verwendung Fehleranflligkeit
Seite 18
Erforderlich ist ein Ansatz der Modularisierung, der Klassen und Individuen behandeln kann!
Seite 19
Seite 20
Th Letschert
Modularisierung mit Klassen: Objektorientierter Entwurf Objektorientierung / technisch: Erweiterung des modularen Ansatzes
Klassen Klassen beinhalten das Gemeinsame von individuellen Exemplaren. Objekte Die Exemplare werden Objekte genannt.
Seite 21
Seite 22
Static
Das Schlsselwort static in einer Klassendefinition sagt, dass es sich um etwas Allgemeines Klassen-bezogenes handelt. Etwas das sich auf die Klasse insgesamt bezieht. Fehlt das Schlsselwort static dann handelt es sich um etwas Objekt-bezogenes, etwas das einzelnen Objekten zugeordnet ist.
Seite 23
Vektorklasse: Alles in Einem zusammengefasst (gekapselt): - Interne Darstellung (Speicherung) der Individuen (Objekte) - Konstruktion - Funktionen Seite 24
public class VektorNutzer { private VektorNutzer() { } public static void main(String[] args) { Vektor a = new Vektor(3, 4); Vektor b = new Vektor(2, 3); Vektor c = Vektor.vektorAdd(a, b); } }
Seite 25
Modularisierung mit Klassen: Objektorientierter Entwurf Beispiel: Modifikation der internen Speicherung
public class Vektor { private int x; private int y; public Vektor(int x, int y) { this.x = x; this.y = y; } public static Vektor vektorAdd(Vektor v1, Vektor v2) { return new Vektor(v1.x + v2.x, v1.y + v2.y); } etc }
public class VektorNutzer { public static void Vektor a Vektor b Vektor c } } Seite 26 main(String[] args) { = new Vektor(3, 4); = new Vektor(2, 3); = Vektor.vektorAdd(a, b);
+
5 7
2 3 5 7 nachher
Seite 27
2 b 3
a
3 4 vorher
a.add(b)
5 a 7 nachher
this : dieser
Vektor (ich), der den Code gerade ausfhrt. this.x : das x von diesem Vektor (von mir)
Anwendungscode
Vektoraddition ist hier eine Vernderung eines Vektors mit Hilfe eines anderen (v2). Nicht eine Funktion, die aus zwei Vektoren einen neuen macht.
Seite 28
Modularisierung mit Klassen: Objektorientierter Entwurf Auch Daten knnen statisch (d.h. Klassen-bezogen) sein
class Vektor { int x = 0 int y = 0 Vektor(x, y) { this.x = x this.y = y } static Vektor nullVektor = new Vektor(0,0) }
Klasse Klassen-Komponente
Vektor v = Vektor.nullVektor;
Seite 29
public class C { private static int a; private int b; public void m(int c) { int d = 0; d = a+b+c+d; .... } public static void f(int c) { int d = 0; d = a+b+c+d; .... } }
Klassen-Variable:
Variable die zu einer Klasse insgesamt gehrt statische Variable
Methode:
Funktion die zu jedem Objekt einer Klasse gehrt auch: nicht-statische Methode
Baer
Instanzierung (Objekt-Erzeugung) brumm
Klasse = Typ / Konstruktions-Muster fr Objekte Definition: ohne static vor der Definition von Methoden oder Variablen Aufruf einer Methode: Objekt-Name . Methoden-Name (..Parameter..)
(Aufruf Methode anderes Objekt) Methoden-Name (..Parameter..) (Aufruf Methode gleiches Objekt)
Baer
new
brumm brumm
public final class Baer { public final class Baer { public void sagHallo() { public void sagHallo() { System.out.println("brumm"); System.out.println("brumm"); } } } }
bruno
brumm
probelmBaer
public final class Hallo { public static void main(String[] args) { Baer bruno = new Baer(); Baer problemBaer = bruno; Baer knut = new Baer(); bruno.sagHallo(); problemBaer.sagHallo(); knut.saghallo(); } }
knut
Eine Br-Klasse Zwei Br-Objekte Drei Br-Variablen
new - erzeugt ein Objekt als neues Exemplar (neue Instanz) der Klasse - und liefert einen Verweis auf das Objekt Die Zuweisung kopiert den Verweis
Seite 32
Jeder Br hat seine eigene Laune: Pro Br gibt es eine Variable gutGelaunt Bren werden einzeln gestreichelt: Hat Auswirkung auf die Laune eines bestimmten Bren. Bei jedem Aufruf ein anderer Wert: Pro Methodenaufruf neu erzeugt Nur lokal fr den Algorithmus notwendig: Pro Methodenaufruf neu erzeugt
Seite 34
gutGelaunt Methodenaufrufe
2
sagHallo main
n bruno
Stack
Seite 35
Konstruktor
initialisiert Objekte
wird bei Aufruf von new aktiviert wird benutzt um das neue Objekt mit Initial-Werten zu belegen
1-ter Konstruktor
this.b : mein b, das b des aktuellen Objekts (das Objekt, das die Methode gerade ausfhrt)
Seite 36
Konstr.-Beispiel, Default-/Standard-Konstruktor
public class Baer { public class Baer { private static String geBrumm1 = "BRUMM"; private static String geBrumm1 = "BRUMM"; private static String geBrumm2 = "GRRRR"; private static String geBrumm2 = "GRRRR"; private boolean gutGelaunt; private boolean gutGelaunt; public Baer(){ public Baer(){ gutGelaunt = true; gutGelaunt = true; } } public Baer(boolean gutGelaunt){ public Baer(boolean gutGelaunt){ this.gutGelaunt = true; this.gutGelaunt = true; } } } } ..... .....
Der Konstruktor, der zu den Parametern passt, wird aufgerufen.
Konstruktor ohne Parameter : Default(Standard-) Konstruktor
Die Laune kann explizit gesetzt werden Der Standard-/DefaultBr ist gut gelaunt
Seite 37
Konstruktoren Konstruktoren werden nach der Initialisierung durch Zuweisung ausgefhrt. Klassen ohne jede Konstruktor-Definition haben automatisch einen (impliziten) Standard-Konstruktor (ohne Aktionen) Klassen mit mindestens einer expliziten Konstruktor-Definitionen haben keinem Standard-Konstruktor, wenn er nicht explizit definiert wird.
public class Baer { public class BaerString { private static geBrumm1 = "BRUMM"; private static String geBrumm1= ="GRRRR"; "BRUMM"; private static String geBrumm2 private static String geBrumm2 = "GRRRR"; private boolean gutGelaunt; private boolean gutGelaunt; } ... ... } public Baer(){ } } } public class Baer { public class BaerString { private static geBrumm1 = "BRUMM"; private static String geBrumm1= ="GRRRR"; "BRUMM"; private static String geBrumm2 private static String geBrumm2 = "GRRRR"; private boolean gutGelaunt; private boolean gutGelaunt; public Baer(boolean gutGelaunt){ publicthis.gutGelaunt Baer(boolean gutGelaunt){ = gutGelaunt; this.gutGelaunt = gutGelaunt; } } ... ...
Seite 38
Seite 39
Klassen-Initialisierer
} Klassen-Initialisierer: Anweisungsfolge in der Klassendefinition wird einmal bei der Initialisierung der Klasse ausgefhrt
Seite 40
Initialisierungsreihenfolge
2. Objektvariablen
1. implizite Zuweisung 2. explizite Zuweisung 3. Objekt-Initialisierer 4. Zuweisungen in einem Konstruktor
Seite 41