Gedankliche Konzepte hinter der Objektorientierung:
Objekte, die jeweils eine Identität haben und einander Nachrichten schicken
Objekte haben Lebensdauer
Referenz: Damit ein Objekt dem anderen eine Nachricht schicken kann, muss es das andere kennen: Es besitzt eine Referenz auf das andere Objekt.
Objekte: Personen, Dokumente, Zahlen, Wahrheitsbereiche
Nachrichten: Schreibe dich ein, Drucke Dich aus, +, -
Identität: Objekte verhalten sich wie Gegenstände in der realen Welt.
(Autos, Lampen, Telefone, Lebewesen, etc.)
Ein Objekt kann nicht an zwei Orten gleichzeitig sein.
Auto wird umlackiert: Ändert seine Identität
Nachrichten und Methoden:
- Auftragserteilung
- Auftragsdurchführung
K. sagt Buchhandlung: "Möchte Buch". Sie schreibt dafür einen Brief
1. Frau K. lösst Aktion aus. Schickt Nachricht.
2. Die Buchhandlung besitzt eine Methode, die an sie gesendete Nachricht zu verarbeiten.
Nachrichtenversand und Zustandsänderung
Klassifikation und Vererbung
Objekte kathegorisieren:
1. Einzelhandelsgeschäft
1.1. Lebensmittelladen
1.2. Buchladen
1.2.1. Kinderbuchladen
1.2.2. Fachbuchhandlung
1.3. Möbelgeschäft
I.) Superklasse
II.) Subklassen
Abstrakte Klassen: Keine Objekte, sondern: Gemeinheiten von Subklassen zusammenfassen
Vererbung: Eigenschaften und Methoden, die mehreren Klassen gemeinsam sind, brauchen nur ein Mal in der übergeordneten Klasse beschrieben werden und können von den Subklassen geerbt werden
1. Objekte
2. Identität
3. Nachrichten und Methoden
4. Nachrichtenversand und Zustandsänderung
5. Klassifikation und Vererbung
Gefahr: Prozedurale Programmierung nicht mit Objektorientierung verwechseln!
a) Modellierung von Information und Verarbeitung
Prozedurale Programmierung
1. Modellierung der Information
2. Modellierung der Verarbeitung
Prozedural: Beide stark getrennt.
Informationen: Grunddaten: Ganze Zahlen, Boolesche Werte, Zeichen, Zeichenketten, ...
In Variablen gespeichert.
Variablen lassen sich in Arrays und Records organisieren
Grundmodell der Verarbeitung in prozeduralen Programmiersprachen: Zustandsänderung
b) Sicht der Programmierenden
c) Strukturierung und Datenkapselung:
Erlaubt in natürlicher Weise die Strukturierung der Verarbeitung
Es bietet wenig Möglichkeiten, um die Teile des Zustands mit den auf ihm operierenden Prozeduren zusammen zu fassen
Und: Kapselung von Daten erreichen
d) Erweiterbarkeit:
Strenge Typisierung
Typkonzepte verbessern zwar die statische Überprüfbarkeit eines Programms, erschweren aber die Anpassbarkeit
Die Typen einer Prozedur p sind fest vorgegeben.
Wird ein Typ erweitert oder modifiziert, entsteht ein neuer Typ, dessen Elemente von p nicht mehr akzeptiert werden.
e) Zuordnung Prozeduraufruf - Prozedurausführung
Sollen unterschiedliche Daten zu unterschiedlichen Programmabläufen führen, müssen Fallunterscheidungen programmiert werden.
Objektorientiert: Binden
f) Parallelität: Die prozedurale Programmierung basiert auf einem sequentiellen Ausführungsmodell. Um Parallelität ausdrücken zu können, muss das Grundmodell erweitert werden.
a) Modellierung von Information und Verarbeitung
b) Sicht der Programmierenden
c) Strukturierung und Datenkapselung:
d) Erweiterbarkeit:
e) Zuordnung Prozeduraufruf - Prozedurausführung
f) Parallelität: Die prozedurale Programmierung basiert auf einem sequentiellen Ausführungsmodell. Um Parallelität ausdrücken zu können, muss das Grundmodell erweitert werden.
Objektorientierung:
a) Modellierung von Information und Verarbeitung:
In der objektorientierten Programmierung bilden Objekte eine Einheit aus Daten und Methoden
b) Sicht der Programmierenden
c) Strukturierung und Datenkapselung:
Jedes Objekt hat eine klar festgelegte Schnittstelle, die beschreibt, welche Nachrichten es versteht
d) Erweiterbarkeit:
e) ...
Objektorientierte Programmiersprachen, 50 Jahre alt
Simula67
Smalltalk
1. Softwaretechnische Simulation
2. Konstruktion interaktiver, grafischer Benutzeroberflächen
3. Programm-Wiederverwendung
4. Verteilte Programmierung
Begrifflich unterscheiden wir, zwischen:
1. Objekten
2. Werten
objects
values
1. Zustand (Objekt, hat Zustand: Auto bekommt Delle, Mensch neue Frisur, ...)
2. Identität: Objekte können sich vollkommen gleichen, ohne denselben Zustand zu haben
3. Lebensdauer
4. Aufenthaltsort
5. Verhalten:
Werte, Typen und Variablen in Java:
byte
short
int
long
float
double
char
boolean
Konstanten des Typs long haben L als Postfix
#################################################################################
Ein Wert ist in Java
- Ein Element eines Basisdatentypen
- Eine Objektreferenz
- die spezielle Referenz null , die auf kein Objekt verweist.
Referenz auf ein Objekt:
- Objekt obj
- Variablen a, b
- a und b zeigen auf obj
Am besten stellt man sich eine Referenz als eine Adresse für ein Objekt
vor.
Lokale Referenzen sind das gleiche wie Zeiger in der imperativen Programmierung.
Arrays in Java
Jedes Array(-Objekt) besitzt ein unveränderliches Attribut length vom Typ int
Wenn die von einem Array referenzierten Arrays nicht alle gleich lang sind, spricht man auch von Ragged Arrays.
char [] a;
char [] b;
char [][] c;
Operationen:
Zuweisung: ...
public class Test {
public static void main(String[] args) {
Anweisungsblock
}
}
1. Um den Wert eines Ausdrucks auf der Standardausgabe auszugeben,
können Sie die folgende Anweisung verwenden:
System.out.println(Ausdruck);
System.out.print(Ausdruck);
2. Um aus einer Zeichenkette (Typ String), die aus einer Ziffernfolge be-
steht, die entsprechende Ganzzahl (int) zu erhalten, können Sie sich an
folgendem Beispiel orientieren:
String s = "1234";
int i = Integer.parseInt(s);
int i = Integer.parseInt(s);
3. Strings lassen sich mit dem Operator + untereinander und mit anderen
Werten paarweise verketten.
#############################################################
Klassische Kontrollstrukturen.
if (boolescher_Ausdruck) Anweisung
und
if (boolescher_Ausdruck) Anweisung1 else Anweisung2
while (boolescher_Ausdruck) Anweisung
do Anweisung while (boolescher_Ausdruck);
for (Init-Ausdruck ; boolescher_Ausdruck ; Ausdruck) Anweisung
for (Variablendeklaration : Ausdruck) Anweisung
for-each
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Lies: Fuer jedes Element im Array ...
for (int elem : arr) {
System.out.print(elem + " ");
}
System.out.println();
switch-Anweisung.
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("31 Tage");
break;
case 2:
System.out.println("28 oder 29 Tage");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println("30 Tage");
break;
default:
System.out.print("Ungueltiger Monat!");
break;
}
Abfangen von Ausnahmen
try
try-Block
catch (AusnahmeTyp Bezeichner) catch-Block1
...
catch (AusnahmeTyp Bezeichner ) catch-BlockN
finally finally-Block
String str = "007L";
int m;
try {
m = Integer.parseInt(str);
}
catch(NumberFormatException e) {
System.out.println("str ist kein int-Wert");
m = 0;
}
System.out.println(m);
public class Quotient {
public static void main(String[] args) {
try {
int m = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
int ergebnis = m / n;
System.out.println(ergebnis);
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Falsche Argument-Anzahl.");
}
catch (NumberFormatException e) {
System.out.println("Mind. ein Argument ist kein int-Wert.");
}
catch (ArithmeticException e) {
System.out.println("Division durch null.");
}
finally {
System.out.println("Programmende.");
}
}
}
##########################################################################################
Objektorientierte Programmierung mit Java
1. person (Name, birthday)
1.1. student (wie person + matricular number, semester)
1.2. employee (wie person + date of hire, salary bracket)
1.2.1. scientific employee (wie employee + faculty, field of teaching)
1.2.2. administrative employee (wie employee + department)
- Objekte
- Klassen
- Methoden
- Konstruktoren
Zustand: Wird durch mehrere Attribute realisiert
Attribute: Objektlokale Variablen - wie Methoden: Funktionen
public class Person {
String name;
int birthday; /* in der Form JJJJMMTT */
}
Default-Konstruktur
new Person()
Konstruktor hin zu fügen:
public class Person {
String name;
int birthday; /* in der Form JJJJMMTT */
Person(String name, int birthday) {
this.name = name;
this.birthday = birthday;
}
}
Das Schlüssel-wort this steht dabei für das „das Objekt, in dem wir uns gerade befinden“,
this.name bezeichnet also das Attribut name dieses Objekts.
public class Person {
String name;
int birthday; /* in der Form JJJJMMTT */
Person(String name, int birthday) {
this.name = name;
this.birthday = birthday;
}
void print() {
System.out.println("Name: " + this.name);
System.out.println("Geburtsdatum: " + this.birthday);
}
boolean isBirthday(int date) {
return birthday % 10000 == date % 10000;
// Das Prozentzeichen ist der Modulo-Operator, welcher
// den Rest einer ganzzahligen Division liefert.
}
}
this-Object = self-Object
Spezialisierung und Vererbung
Dass eine Klasse eine Erweiterung einer anderen Klasse (deren Subklasse) ist, wird mit dem Schlüsselwort extends aus-
gedrückt.
Da eine Klasse in Java eine spezielle Art Typ ist, wird durch dieses Subclassing gleichzeitig festgelegt, dass der Typ der Subklasse Subtyp des Typs der Superklasse ist.
public class Student extends Person {
int matriculationNr;
int semester;}
Student(String name, int birthday, int matriculationNr, int semester) {
super(name, birthday);
this.matriculationNr = matriculationNr;
this.semester = semester;
}
void print() {
super.print();
System.out.println("Matrikelnr: " + matriculationNr);
System.out.println("Semesterzahl: " + semester);
}
int getMatriculationNr() {
return matriculationNr;
}
Man bezeichnet dies als Überschreiben der Methode der Superklasse.
Schlüsselwort super
super.print();
public class PersonPrintTest {
public static void main(String[] args) {
Person[] persons = new Person[3];
persons[0] = new Person("Meyer", 19831007);
persons[1] = new Student("Mueller", 19641223, 6758475, 5);
persons[2] = new Student("Planck", 18580423, 3454545, 47);
}
for (int i = 0; i < persons.length; i = i + 1) {
persons[i].print();
System.out.println();
}
}
Wichtige Schreibweisen:
public class Progname {}
public static void main(String[] args) {}
System.out.prinln();
System.out.print();
String gross geschrieben
this
super
extends
class subclass extends superclass {}
########################################## Objekte ###############################################
1. Klassenkonzept
2. Prototyp-Konzept
1. Klassenkonzept
Nicht, die Objekte werden beschrieben, sondern die Klassen
2. Prototyp-Konzept
Neue Objekte werden durch klonen existierender Objekte erzeugt.
Klonen eines Objekts nennt man erzeugen eines Objekts.
Eigenschaft und Verhalten
- Welche Zustände kann ein Objekt annehmen
- Auf welche Nachrichten kann und soll es reagieren
- Wie sehen die Methoden, bei Nachrichten aus.
Eine Klasse beschreibt eine Menge gleichartiger Objekte.
Klassendeklarationen, Attribute und Objekte.
Schlüsselwort class
class
Modifikatorenliste class Klassenname {
Liste von Attribut-, Konstruktor und Methodendeklarationen
}
Typen, die durch eine Klasse deklariert sind, nennen wir Klassentypen
Objektlokale Variable: Ein Objekt einer Klasse besitzt für jedes Attribut der Klasse eine objektlokale Variable
Komponenten einer Klasse: Attribute, Konstruktoren, Methoden
Instanzen: Die Objekte einer Klasse werden häufig als Instanzen bezeichnet.
############################################
Methodendeklaration
1. Erweiterte Methodensignatur
2. Methodenrumpf
Methodenrumpf: Anweisungsblock
Methodensignatur:
Modifikatorenliste Ergebnistyp Methodenname (Parameterliste) throws-Definitionen
Modifikatorenliste - wie bei Klassen:
Liste von Schlüsselworten: public, static
Ergebnistyp:
void, ...
throws-Deklaration
#########################################
Konstruktor-Deklaration:
Modifikatorenliste Klassenname (Parameterliste) throws-Definitionen
############################################
Objekt-Erzeugung, Attributzugriff und Methodenaufruf
Syntaktisch ist eine Objekterzeugung ein Ausdruck mit dem Schlüsselwort new
##############################################
##############################################
Die Objekterzeugung wird wie folgt ausgewertet: Zuerst wird eine neue Instanz der Klasse Klassenname erzeugt.
Die Attribute dieses neu erzeugten Objekts sind mit Default-Werten initialisiert.
Anschließend wird der Konstruktor Klassenname aufgerufen.
Terminiert die Auswertung einer Objektgruppe normal, liefert sie eine Referenz auf ein neu erzeugtes Objekt der Klasse Klassenname.
Ausdruck.Attributname
this.Attributname
Methodenaufruf:
Ausdruck.Methodenname (Aktuelle Parameterliste)
###############################################
Java: Klassen zur Beschreibung von Objekten.
Programm: Ansammlung von Klassen
In Java gibt es keine als Hauptprogramm ausgezeichneten Programmteile
class Test1 {
public static void main( String[] args ){
Test2 obj = new Test2();
obj.drucke("Ich bin ein Objekt vom Typ Test2");
}
public void hallo(){
System.out.println("Jemand hat mich gegruesst");
}
}
class Test2 {
public static void main( String[] args ){
(new Test1()).hallo();
}
public void drucke(String s) {
System.out.println( s );
}
}
#########################################
Weiterführende Sprachkonstrukte
Initialisierung und Überladen
Initialisieren von Variablen und Attributen.
Initialisieren von Variablen und Attributen. Lokale Variablen und Attri-
bute können an ihrer Deklarationsstelle initialisiert werden. Beispielsweise
ist das Programmfragment
Wie bereits in Abschnitt 2.1.2.3 beschrieben, werden Attribute bei der
Objekterzeugung mit Default-Werten initialisiert.
Für lokale Variablen gibt es hingegen keine solche automatische Initialisie-
rung, weswegen lokale Variablen explizit initialisiert werden müssen, bevor
das erste Mal lesend auf sie zugegriffen wird.
Java bietet die Möglichkeit Variablen und Attribute durch Voransetzen
des Schlüsselworts final als unveränderlich zu deklarieren: Benannte Konstanten
Für komplexe Initialisierungsaufgaben stellt Java sog. Initialisierungsblöcke
bereit: Statische Initialisierungsblöcke für Klassenattribute und nicht statische
Initialisierungsblöcke für Instanzattribute.
Überladen von Methodennamen und Konstruktoren.
Eine derartige Mehrfachverwendung nennt man Überladen eines Na-
mens.
Eine derartige Mehrfachverwendung nennt man Überladen eines Na-
mens. Methoden mit gleichen Namen müssen sich in der Anzahl oder in den
Typen der Parameter unterscheiden. Dadurch ist es dem Compiler möglich,
die Überladung aufzulösen, d.h. für jede Aufrufstelle zu ermitteln, welche von
den Methoden gleichen Namens an der Aufrufstelle gemeint ist.
String:
Konstruktor:
1.) Der Konstruktor mit leerer Parameterliste liefert ein String-Objekt, das die leere Zeichenkette liefert
2.) Mit Parameter vom Typ String, liefert ein String-Objekt, das die gleiche Zeichenkette, wie der Parameter repräsentiert
3.) String (char [] value) liefert, String-Objekt mit den im Array übergebenen Zeichen
4.) String(char[] value, int offset, int count)
Die Methoden mit Namen indexOf bieten vier Möglichkeiten, den In-
dex des ersten Vorkommens eines Zeichens bzw. einer Teil-Zeichenkette zu
ermitteln.
1.) Sucht nach dem gegebenen Zeichen ch
2.) Sucht nach der Zeichenkette str
3.) str an der Stelle fromIndex
length (Methode)
charAt (Methode)
equals (Methode)
########################################################################
Klassenmethoden und Klassenattribute
Attribute und Methoden können in Java nicht nur Objekten zugeordnet wer-
den, sondern auch Klassen.
Deklaration und Bedeutung.
Deklaration und Bedeutung. Klassenmethoden bzw. Klassenattribute werden
deklariert, indem man eine Methoden- bzw. Attributdeklaration mit dem
Schlüsselwort static beginnt.
Statische Methoden bzw. Attribute genannt.
Wie wir gesehen haben, besitzt jedes Objekt für jedes normale Attribut
seiner Klasse eine objektlokale Variable
Wie wir gesehen haben, besitzt jedes Objekt für jedes normale Attribut
seiner Klasse eine objektlokale Variable (vgl. die Bemerkungen zum Begriff
„Instanzvariable“ auf S. 73). Im Gegensatz dazu entspricht jedem Klassen-
attribut genau eine Variable, unabhängig davon, wie viele Objekte der Klasse
erzeugt werden. Insbesondere existiert diese Variable auch, wenn gar kein
Objekt der Klasse erzeugt wird. Für den Zugriff auf Klassenattribute wird
die Syntax Klassenname.Attributname verwendet. Innerhalb der Klassendefi-
nition reicht die Angabe des Attributnamens.
Klassenmethoden ähneln Prozeduren der prozeduralen Programmierung.
Sie besitzen keinen impliziten Parameter („this“). Deshalb ist es auch nicht
möglich, innerhalb von Klassenmethoden auf die in dieser Klasse deklarier-
ten Instanzvariablen oder „normalen“ (nicht statischen) Methoden zuzugrei-
fen, ohne die gemeinte Instanz explizit zu benennen. Oft sollen Klassenme-
thoden auch ausführbar sein, wenn überhaupt keine Instanz der Klasse exis-
tiert. Selbstverständlich darf eine Klassenmethode auf die zugehörigen Klas-
senattribute zugreifen. Ein typisches Beispiel für eine Klassenmethode ist die
Methode mit Namen main, die zu jedem ausführbaren Programm gehört
(vgl. S. 78).
S. 84
1. Globale Konstanten und Funktionen
2. Kontrolle über die Objekterzeugung
3. Fallweise Erzeugung von Subklassen-Instanzen
4. Modularisierung
5. Informationen über alle Instanzen einer Klasse
Rekursive Klassendeklarationen
Eine Definition wird rekursiv genannt, wenn die definierte Größe im definie-
renden Teil vorkommt. Beispielsweise ist eine Methode m rekursiv definiert
(oder auch: „m ist rekursiv“), wenn m in ihrem eigenen Rumpf aufgerufen
wird.
Moderne Programmiersprachen unterstützen rekursive Definitionen bzw.
Deklarationen von Prozeduren (bzw. Funktionen, Prädikaten oder Methoden,
je nachdem, was die betreffende Sprache vorsieht) und Datentypen. Rekursi-
ve Datentypdeklarationen sind bei vielen prozeduralen und objektorientier-
ten Programmiersprachen allerdings nur unter Verwendung expliziter Zei-
gertypen möglich.
Doppelt verkettete Listen. Ein Behälter (engl. container) ist ein Datentyp
zum Speichern von Elementen bzw. Objekt-Referenzen. Eine Liste ist ein Be-
hälter, in dem ein Element mehrfach enthalten sein kann und in dem die Ele-
mente geordnet sind.
spezielles Entry-Objekt
2.2
Kapselung und Strukturierung von Klassen
2.2.1
Kapselung und Schnittstellenbildung: Erste Schritte
Bisher sind wir weitgehend davon ausgegangen, dass alle, die ein Objekt bzw.
eine Klasse nutzen, auf alle Attribute zugreifen, alle Attribute verändern, so-
wie alle Methoden und Konstruktoren aufrufen können13.
Klasseninvarianten.
Information Hiding
Geheimnisprinzip
Methoden und Konstruktoren als privat
Zugriffsmodifikators private
Schnittstellenbildung. Private Attribute, Methoden und Konstruktoren ei-
ner Klasse stehen den Benutzenden nicht zur Verfügung und gehören
dementsprechend auch nicht zur öffentlichen Schnittstelle der Klasse.
2.2.2
Strukturieren von Klassen
Eine Klasse, die innerhalb
einer anderen deklariert ist, wird in Java eine innere Klasse genannt.
Innere Klassen
1. Sie strukturiert die Programme.
2. Sie legt Gültigkeitsbereiche für Namen fest.
Statische innere Klassen.
#########################################
Kapselung und Strukturierung von Klassen
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Bisher sind wir weitgehend davon ausgegangen, dass alle, die ein Objekt bzw.
eine Klasse nutzen, auf alle Attribute zugreifen, alle Attribute verändern, so-
wie alle Methoden und Konstruktoren aufrufen können13.
Strukturierung von Programmen: Pakete
Aspekte zu beachten:
1. Auffinden, Verstehen: Die gute Strukturierung der Klassen eines großen
Programms erleichtert es, den Zusammenhang zwischen Softwareent-
wurf und Programmcode herzustellen und damit das Programm zu
verstehen. Allen, die eine Bibliothek nutzen, sollte es leicht gemacht
werden, Klassen in der Bibliothek ausfindig zu machen, die ihnen bei
ihrer Implementierung helfen können.
2. Pflege: Die Strukturierung der Klassen sollte die Abhängigkeiten zwi-
schen den Klassen widerspiegeln können, um Wartung und Pflege der
Programme zu verbessern.
3. Zugriffsrechte, getrennte Namensräume: Klassen sollten zu Modulen
zusammengefasst werden können, sodass man den Zugriff von einem
Modul auf ein anderes einschränken kann und in verschiedenen Modu-
len getrennte Namensräume hat.
4. Getrennte Übersetzung: Im Zusammenhang mit der Strukturierung
muss auch festgelegt werden, welche Programmteile unabhängig von-
einander übersetzt werden können.
Java benutzt sogenannte Pakete zur Modularisierung von Programmen
Menge sogenannter Übersetzungseinheiten.
package Paketname;
Liste von import-Anweisungen
Liste von Typdeklarationen
Typdeklaration
##############################################################################
##############################################################################
##############################################################################
Pakete: Modularisierung von Programmen
Pakete besitzen einen eindeutigen Namen
Werden nicht nicht expliziet deklariert
Klassen deklarieren zu welchem Paket sie gehören
Paket: Umfasst Übersetzungseinheiten
"package" Paketname
Liste von Import-Anweisungen
Liste von Typdeklarationen
Typdeklaration
1. Entweder: Klassendeklaration
2. Oder: Schnittstellendeklaration
Default-Page
Im Dateisystem: Übersetzungseinheit entspricht einer Quellcode-Datei mit *.java Endung
Beispiel, um zu zeigen, wie Übersetzungseinheiten aussehen:
Fiktiver Internet-Provider:
1. HotlineEmployee: Kann von Kunden angerufen werden
2. Ticket: Angaben zur Störung, Kundendaten, Erstellungsdatum, Datum der Erledigung
3. TickSystem: Verkettete Liste in der man Tickets "vorne" einstellen und der man sie "hinten" entnehmen kann (FIFO)
4. Technican: Entnimmt ein Ticket aus der Liste, bearbeitet das Problem
5. LinkedList: Eine allgemein verwendbare Listenklasse in der beliebige Objekte abgelegt werden können
Wir teilen die Klassen auf zwei Pakete auf:
de.feunet.support
de.feunet.util
Paket: de.feunet.util:
de/feunet/util/LinkedList.java
Paket de.feunet.support
de/feunet/support/HotlineEmployee.java
de/feunet/support/Technican.java
de/feunet/support/TicketSystem.java
de/feunet/support/Ticket.java
Benutzung von Paketen:
Aber 3 Einschränkungen:
1. Kapselung auf der Ebene von Paketen
2. Erreichbarkeit
3. Eindeutigkeit
>>>>>>>>>>>>>>>>>>>>>>> Hier weitermachen <<<<<<<<<<<<<<<<<<<<<<<<<<
Kapitel III
Typisierung und Subtyping
Motivation von Subtyping im Kontext von Behälterklassen
Spezialisierung
Abstraktion
Schnittstellentypen für die Abstraktion
Nicht alle objektorientierten Programmiersprachen brauchen ein Typensystem
Deklarationstyp = statischen Typ
dynamischer Typ, zur Laufzeit
statische Typsicherheit
Jede Klasse in Java definiert einen Typen
Nachteile von Typisierung
1. Schreibaufwand wir größer
2. Wirkt wie ein Korsett
Beispiel, Klasse, List, die eine mit den Values vom einen Typ, die andere vom anderen (String)
Wir müssten im Quelltext alles ändern.
Stehen im Gegensatz zum Anliegen der Objektorientierung, kompakte, einfach zu wartende Programme zu schreiben
Einfaches Model:
Behälterklasse, Container.
Behälter für genau ein Objekt
Es gibt zwei Ansätze, diese Inflexibilität zu überwinden, ohne die Vorteile der Typisierung zu verlieren
1.) Man unterstützt Subtyping
2.) Typen, bzw. Klassen parametrisieren
+++ +++ Container +++ +++
1.) ...
2.) OO-Programmiersprachen unersützen Allgemeinsten Typ, der definitionsgemäß der Supertyp aller Objekttypen ist.
Object
Die Subtyp-Beziehung darf keine Zyklen enthalten. Folgende Deklara-
tionen sind also beispielsweise unzulässig:
class A extends B {}
class B extends C {}
class C extends A {}
Casts:
Nachteil: Casts - Object: Compiler weißt solche Casts zurück
instanceof-Operator
Behälterklassen
Behälterklassen lassen sich bauen, in denen man Objekte verschiedenen Typs ablegen kann.
Vorschau, Lösung: Parametrisierung von Klassen
Basisdaten und Subtyping
Zwischen Basisdaten: Keine Subtypbeziehung
Die Basisdatentypen stehen in keiner Subtyp-Beziehung zu den Referenztypen
Auch nicht zu Object
Man muss die Zahlen in Objekte verpacken
Sie werden Wrapperklassen genannt, da die Instanzen dieser Klassen die Werte quasi in Objekte einpacken
value
Instanzvariable value
Schlecht lesbar, kurz und gut:
Klasse Int
class int {
integer value;
getvalue();
putvalue(integer)
}
Schlecht lesbar und: Speicherplatz.
Deswegen Java 5.0: Autoboxing
Automatisches Packen und Entpacken:
Boxing und Unboxing
#########################
Subtyping bei Arrays
In Java ist jeder Array-Typ ein Subtyp von Object
###########################
Klassifikation von Objekten
Klassifikation ist eine Technik, um Wissen über Begriffe, Dinge und deren Eigenschaften zu strukturieren
Allgemeine Begriffe stehen oben, die spezielleren unten: Hierarchie:
1.) Recht
1.1.) Öffentliches Recht
1.2.) Privatrecht
1.2.1.) Bürgerliches Recht
1.2.2.) Handelsrecht
1.2.3.) Urheberrecht
1.3.) Kirchenrecht
1.) Musikinstrumente
1.1.) Saiteninstrumente
1.2.) Blasinstrumente
1.2.1.) Holzblasinstrumente
1.2.2.) Blechblasinstrumente
1.3.) Schlaginstrumente
...
Parallelogramm
/ \
/ \
/ \
Route Quadrat
\ /
\ /
\ /
Quadrat
Ein Holzblasinstrument ist ein Blasinstrument und natürlich ein Musikinstrument
Ein Qudrat ist eine Route
Aussage: "A ist B"
ist-ein-Beziehung (is-a-relation)
Spezialisierung und Abstraktion
1. Das Spezialisieren von Klassen und Typen
2. Das Abstrahieren, d.h. Verallgemeinern von Typen
Spezialisierung:
Hinzufügen "speziellerer" Eigenschaften, Verfeinern des Begriffs
Grundkomponenten
#########################
Abstraktion, Schnittstellentypen (Interfaces)
Abstraktion (Verallgemeinerung)
###########################
##########################
###########################
Subtyping und Vererbung
Subtyping genauer betrachtet
Interfaces und Subtyping
Drei Möglichkeiten, Typen zu deklarieren:
1.) Klassendeklaration
2.) Interfacedeklarationen
3.) Deklaration von Arrays
Zusammenfassend: Referenz- oder Objekttypen
Interface: Neuer Typ, legt aber nur die Schnittstelle fest
Ein Interface legt nur die öffentliche Schnittstelle fest und besitzt keine eigene Implementierung
############################
Deklaration von Interfacetypen
Die Deklaration eines Interfacetyp legt fest:
- Typnamen
- Namen benannter Konstanten
- erweiterte Signaturen der Methoden
Kein public nötig, da letzteren beiden immer öffentlich
Konstantendeklarationen in Interfaces
interface Farben
{
byte ROT = 0;
byte GRUEN = 1;
byte BLAU = 2;
byte GELB = 3;
}
Deklaration von Subtypen
T ist Supertyp von S
S ist Subtyp von T
S ist direkter Subtyp von T, wenn S Subtyp von T ist und es keinen Subtyp U zwischen S und T gibt
1. Interfacetypen als Subtypen
2. Klassentypen als Subtypen