/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/old-cs-2-03/java/java5.txt


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)
 
 ###########################
 
 Vererben