[Go to site: main page, start]

0% fanden dieses Dokument nützlich (0 Abstimmungen)
65 Ansichten82 Seiten

Softwareentwicklung

Hochgeladen von

Master Guanyu
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen
0% fanden dieses Dokument nützlich (0 Abstimmungen)
65 Ansichten82 Seiten

Softwareentwicklung

Hochgeladen von

Master Guanyu
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen

Softwareentwicklung ● 1-82

Softwareentwicklung

Softwareentwicklung
Skriptum zur Vorlesung - 01.01.2023

Dipl.-Ing. Paul Panhofer BSc.1∗

1 ZID, TU Wien, Taubstummengasse 11, 1040, Wien, Austria

Abstract:
MSC: [Link]@[Link]
Keywords:

Contents 1.5.1. Datenstruktur Stack 14


1.5.2. Datenstruktur Heap 14
1. Grundlagen der objektorientierten 1.5.3. Programmartefakt Zeiger 14
Programmierung 4 1.6. Implizite Vererbung 15
1.1. Konzept der Objektorientierung 4 1.6.1. Verhalten der Object Klasse 15
1.1.1. Objekte 4 1.6.2. Methode: ToString 15
1.1.2. Objektorientierung 5 1.6.3. Methode: Equals 16
1.2. Klassen und Objekte 5 1.7. Anweisungsblock 17
1.2.1. Objekte 5 1.7.1. Anweisungsblock 17
1.2.2. Eigenschaften von Objekten 6 1.7.2. Gültigkeitsbereich von Variablen 18
1.2.3. Implementierung 7 1.7.3. Fallbeispiel: Gültigkeitsbereich 18
1.8. Klassenobjekt 19
1.2.4. Klassen 7
1.8.1. Klassenobjekt vs. Objekt 19
1.3. Elemente einer Klasse 8
1.8.2. Motivation: Klassenobjekt 19
1.3.1. Klassenelement: Variablen 8
1.9. Interface 20
1.3.2. Objektschachtelung 8 1.9.1. Interne Schnittstelle 20
1.3.3. Zugriffsoperatoren 9 1.9.2. Externe Schnittstelle 20
1.3.4. Klassenelement: Property 9 1.9.3. Interface 21
1.3.5. Klassenelement: Konstruktor 10 1.9.4. Implementierung vs. Vererbung 21
1.3.6. Klassenelment: Methode 11 1.9.5. Definition eines Interfaces 22
1.3.7. this Referenz 12 1.9.6. Analyse: Interface 22
1.4. Vererbung 12 1.9.7. Objektorientiertes Design 23
1.4.1. Fallbeispiel: Person 12 1.9.8. Fallbeispiel: DuckSimulator 23
1.4.2. Konzept: Vererbung 13
2. Collections 28
1.4.3. Abstrakte Klassen 13
2.1. Datenstrukturen 28
1.5. Speicherverwaltung 14
2.1.1. Grundlagen 28
2.2. Datenstruktur: List 29

E-mail: [Link]@[Link] 2.2.1. Verhalten von Listen 29

1
Softwareentwicklung

2.2.2. foreach Schleife 31 5.2.2. Klassenmethode: CreateDirectory() 63


2.3. Datenstruktur: Stack 32 5.2.3. Klassenmethode: Delete() 64
2.3.1. Verhalten von Stacks 32 5.2.4. Klassenmethode: Move() 64
2.3.2. Fallbeispiel: Stack 32 5.2.5. Klassenmethode: GetDirectories() 65
2.4. Datenstruktur: Queue 35 5.2.6. Klassenmethode:
2.4.1. Verhalten von Queues 35 GetFileSystemEntries() 65
2.4.2. Fallbeispiel: Queue 36 5.2.7. Klassenmethode: GetFiles() 66
2.5. Datenstruktur: Dictionary 37 5.2.8. Klassenmethode: GetParent() 66
2.5.1. Fallbeispiel: Array vs. Dictionary 37 5.2.9. Klassenmethode:
2.5.2. Fallbeispiel: Dictionary 38 GetDirectoryRoot() 66
2.5.3. Wertezugriff 40 5.2.10. Klassenmethode:
2.6. Indexer 40 GetCurrentDirectory() 66
2.6.1. Indexer 40 5.3. Filesystem: Datei 67
5.3.1. Klassenmethode: Exists() 67
3. Datentyp: String 43 5.3.2. Klassenmethode: WriteAllText() 68
3.1. Instanzieren von Strings 43 5.3.3. Klassenmethode: CreateText() 68
3.1.1. String Klasse 43 5.3.4. Klassenmethode: Delete() 69
3.1.2. Instanzieren von Strings 43 5.3.5. Klassenmethode: ReadLines() 69
3.1.3. Stringliterale 44 5.3.6. Klassenmethode: AppendText() 69
3.1.4. Substrings 44 5.3.7. Klassenmethode: OpenText() 70
3.1.5. Formatstring 45 5.3.8. Klassenmethode: AppendAllLines() 70
3.1.6. StringBuilder 45 5.3.9. Klassenmethode: WriteAllLines() 70
3.2. Stringobjekte 47
3.2.1. Stringobjekte 47 6. Appendix A: Muster 71
3.2.2. Leere Strings 47 6.1. Entwurfsmuster 71
3.2.3. ASCII Code 49 6.1.1. Grundlagen 71
3.2.4. Fallbeispiel: Codierung 49 6.1.2. Arten von Pattern 71
3.3. Objektmethoden 51 6.1.3. Einsatz von Entwurfsmustern 72
3.3.1. Methode: IndexOf() 51 6.1.4. Kategorien von Entwurfsmustern 72
3.3.2. Methode: Contains() 51 6.2. Erzeugermuster 72
3.3.3. Methode: Starts/EndsWith() 51 6.2.1. Erzeugermuster - Singleton 72
3.3.4. Methode: LastIndexOf() 52 6.2.2. Erzeugermuster - Factory 73
6.3. Strukturmuster 75
3.3.5. Methode: Insert() 52
6.3.1. Strukturmuster - Adapter 75
3.3.6. Methode: Split() 52
6.3.2. Strukturmuster - Dekorator 76
3.3.7. Methode: Remove() 53
6.4. Verhaltensmuster 77
3.3.8. Methode: Replace() 53
6.4.1. Verhaltensmuster - Command 77
3.3.9. Methode: ToLower()/ToUpper() 53
6.4.2. Verhaltensmuster - Strategy 79
3.3.10. Methode: Trim() 54
3.4. Klassenmethoden 54 Index 82
3.4.1. Methode: Concat() 54
3.4.2. Methode: Join() 55
3.4.3. Methode: IsNullOrEmpty() 55

4. Exception 57
4.1. Fehlerbehandlung 57
4.1.1. Fehler und Ausnahmen 57
4.1.2. Fehlerbehandlung 58
4.1.3. Programmfluss: Fehlerbehandlung 59

5. FileIO 61
5.1. Filesystem 62
5.2. Filesystem: Verzeichnis 62
5.2.1. Klassenmethode: Exists() 62

2
Softwareentwicklung - Theorieskriptum
.

Grundlagen der objektorientierten


Programmierung
December 14, 2019
Softwareentwicklung

1. Grundlagen der objektorientierten 1.1. Konzept der Objektorientierung


Programmierung
1.1.1 Objekte
Die objektorientierte Programmierung basiert darauf,
Software in Anlehnung an die Gegebenheiten der rea-
len Welt als Objekte aufzufassen.

L | 
Erklärung: Objekte
‚ Objekte verfügen über Eigenschaften, die sie näher
charakterisieren.
‚ Ebenso können Objekte bestimmte Tätigkeiten aus-
führen. Sie können miteinander kommunizieren und
in einer bestimmten Beziehung zueinander stehen.

01. Konzept der Objektorientierung 4

02. Klassen und Objekte 5

03. Elemente einer Klasse 8

04. Vererbung 12

05. Speicherverwaltung 14

06. Implizite Vererbung 15 Fallbeispiel: Automobile


‚ Ein Automobil ist je nach Sichtweise ein mehr oder
07. Anweisungsblock 17 weniger komplexes Objekt, das sich beispielswei-
se durch folgende Eigenschaften beschreiben läßt:
08. Klassenobjekt 19 Hersteller, Typ, Farbe, Zulassungsjahr.

‚ Diese Eigenschaften1 repräsentieren die Daten des


09. Interface 20 Objekts.

‚ Gleichzeitig verfügt ein Auto stets über bestimmte


Fähigkeiten, d.h. es kann bestimmte Funktionen -
Bremsen, Beschleunigen - ausführen. Sie werden mit
Blick auf die objektorientierte Programmierung als
Methoden bezeichnet.

1
Sie werden auch als Variablen bezeichnet.

4
© Paul Panhofer

Abbildung 1. Klassen vs. Objekte

1.1.2 Objektorientierung 1.2. Klassen und Objekte

L Konzept Objekte Die objektorientierte Programmierung ist das


zur Zeit vorherrschende Programmierparadigma.
Unter Objekten versteht man die Zusammen-
fassung von Daten und Funktionen.
1.2.1 Objekte
Dabei gehört ein konkretes Objekt zu einer
Klasse. Eine Klasse wiederum ist der Bauplan Das wichtigste Konzept der objektorientierten Pro-
für Objekte. Dabei können von einer Klasse grammierung ist das Objekt.
beliebig viel Objekte - Instanzen - erstellte wer-
den.
L Objekt
Ein Objekt ist die grundlegende Einheit eines
Erklärung: Objektorientierung
Programms. Zur Laufzeit besteht ein Programm
‚ Als Basis und Vorläufer der objektorientierten Pro- aus einer Menge von Objekten, die unterein-
grammierung gilt die strukturelle Programmie- ader Nachrichten austauschen.
rung, deren Wesen hauptsächlich darauf beruht,
dass eine komplexe Gesamtaufgabe in Teilaufgaben
zerlegt wird. Erklärung: Objekt
‚ Man kann ein Objekt am ehesten als eine Kapsel
‚ Objektorientierte Programmiersprachen haben diese
versteht, die zusammen gehörende Variablen und
Konzepte aufgegriffen und sie um das Klassenkon-
Methoden enthält.
zept erweitert.
‚ Gemeinsam beschreiben die Variablen und Routinen
‚ Die objektorientierte Programmierung fördert dabei
eine Einheit der Software.
insbesondere den Ansatz der Wiederverwendbar-
keit.

5
Softwareentwicklung

Abbildung 2. Programm: System von Objekten

‚ Von außen soll man auf das Objekt nur zugreifen, 1.2.2 Eigenschaften von Objekten
indem man ihm eine Nachricht schickt, das heißt,
Für Objekte werden 3 Eigenschaften unterschieden:
eine Methode des Objekts aufruft.
Identität, Zustand bzw. Verhalten.

Codebeispiel: [Link] Auflistung: Eigenschaften von Objekten


1 // ----------------------------------------
2 // Klasse: [Link]
Identität
3 // ----------------------------------------
4 public class Point { Vereinfacht kann man sich die Identität eines
5 Objekts als seine Adresse im Speicher vorstel-
6 private int _x; len. 2 Objekte sind identisch wenn sie dieselbe
7 private int _y; Adresse im Speicher haben.
8

9 public int X (get; set;)


10 public int Y (get; set;)  Zustand
11 Der Zustand eines Objekts setzt sich aus den
12 public Point(int x, int y){ Werten der Variablen des Objekts zusammen.
13 this._x = x; Er ist in der Regel änderbar.
14 this._y = y;
15 } 2 Objekte sind gleich wenn sie denselben Zu-
16
stand und dasselbe Verhalten haben.
17 public Point(){
18 } 3 Verhalten
19

20 public bool IsEqual(Point p){ Das Verhalten eines Objekts beschreibt, wie
21 return p.X == this.X && p.Y == this.Y; sich das Objekt beim Empfang einer Nach-
22 } richt verhält, das heißt, was das Objekt
23 beim Aufruf einer entsprechenden Methode
24 } macht.


6
© Paul Panhofer

1.2.3 Implementierung 1.2.4 Klassen


Unter der Implementierung einer Methode verstehen Viele objektorientierte Sprachen unterstüzen ein Klas-
wir den Programmcode, der fest legt, was genau beim senkonzept: Jedes Objekt gehört zu genau einer Klas-
Aufruf einer Methode zu tun ist. se.

L Implementierung L Klasse
Die Implementierung aller Methoden eines Eine Klasse beschreibt die Struktur eines Ob-
Objekts und die Deklaration der Variablen des jekts. Die Klasse legt die Implementierung ei-
Objekts bilden die Implementierung des Ob- nes Objekts fest.
jekts.
Ein Objekt einer Klasse wird auch als Instanz
Die Implementierung beschreibt das Verhal- der Klasse bezeichnet.
ten des Objekts.
Codebeispiel: [Link]
1 // ----------------------------------------
Codebeispiel: [Link]
2 // Klasse: [Link]
1 // ----------------------------------------
3 // ----------------------------------------
2 // Klasse: [Link]
4 /*
3 // ----------------------------------------
5 * Implementierung der Klasse Point
4 // Implementierung der Klasse Point
6 */
5 public class Point{
7 public class Point{
6
8
7 private int _x;
9 private int _x,_y;
8 private int _y;
10
9
11 public int X (get; set;)
10 public int X {
12 public int Y (get; set;)
11 get{return _x;};
13
12 set{_x = value;};
14 public Point(int x, int y){
13 }
15 this._x = x;
14
16 this._y = y;
15 public int Y {
17 }
16 get{return _y};
18
17 set{_y = value;};
19 public bool IsEqual(Point p){
18 }
20 return p.X == this.X && p.Y == this.Y;
19
21 }
20 public Point(int x, int y){
22
21 this._x = x;
23 }
22 this._y = y;
24
23 }
25 public class Programm{
24
26
25 public Point(){
27 public static void Main(String[] args){
26
28 // Von der Point Klasse werden 2
27 }
29 // Objekte p1 und p2 angelegt.
28
30 // p1 und p2 werden als Instanzen der
29 public bool IsEqual(Point p){
31 // Klasse bezeichnet.
30 return p.X == this.X && p.Y == this.Y;
32 Point p1 = new Point(2,1);
31 }
33 Point p2 = new Point(4,6);
32 }
34 }
35 }

7
Softwareentwicklung

1.3. Elemente einer Klasse 1.3.2 Objektschachtelung

Die Struktur einer Klasse folgt einem vorgegebenem Klassen können Objekte anderer Klassen als Variablen
Muster. haben.

Codebeispiel: Objektschachtelung
1.3.1 Klassenelement: Variablen 1 // ----------------------------------------
2 // Klasse: [Link], [Link]
Die Werte der Variablen einer Klasse beschreiben den 3 // ----------------------------------------
Zustand eines Objekts. 4 public class Address{
Erklärung: Variablen 5

‚ In einer Klasse kann eine beliebige Zahl von Varia- 6 public String _location;
blen definiert werden. 7 public String _postalCode;
8
‚ Jeder Instanz - Objekt - einer Klasse wird beim Er- 9 public Address(String location, String
zeugen im Speicher Platz für diese Variablen bereit- postalCode){
gestellt. 10 _location = location;
Codebeispiel: [Link] 11 _postalCode = postalCode;
12 }
1 // ----------------------------------------
13 }
2 // Klasse: [Link]
14
3 // ----------------------------------------
15 public class Person {
4 public class Point{
16
5
17 public String _firstName;
6 public int _x;
18 public String _lastName;
7 public int _y;
19 public Address _address;
8
20
9 public Point(int x, int y){
21 public Person(String firstName, String
10 this._x = x;
lastName){
11 this._y = y;
22 _firstName = firstName;
12 }
23 _lastName = lastName;
13 }
24 }
14
25 }
15 // ----------------------------------------
26
16 // Klasse: [Link]
27 // ----------------------------------------
17 // ----------------------------------------
28 // Klasse: [Link]
18 public class Programm {
29 // ----------------------------------------
19
30 public class Programm {
20 public static void Main(String[] args){
31
21 // Anlegen 2er Point Objekte p1 und p2
32 public static void Main(String[] args){
22 Point p1 = new Point(3,3);
33 Address a = new Address("Kirchberg am
23 Point p2 = new Point(4,5);
Wagram","3470");
24
34
25 // Ueberweisen von Werten an die Var-
35 Person p = new Point("Jonas","Nage");
26 // iablen der Objekte. Fuer die Objekte
36 p._address = a;
27 // p1 und p2 wird eine eigene Variable
37
28 // _x im Speicher angelegt.
38 // Ausgabe des Wohnorts einer Person
29 p1._x = 7;
39 [Link](p._address._location);
30 p2._x = 8;
40 }
31 }
41
32
42 }
33 }

❑ ❑

8
© Paul Panhofer

Abbildung 3. Zugriffsoperatoren

1.3.3 Zugriffsoperatoren 1.3.4 Klassenelement: Property


Mit Properties wird der Zugriff auf die Variablen eines
L Zugriffsoperatoren Objekts gesteuert.
Zugriffsoperatoren legen fest, wer auf die Va- Erklärung: Properties
riablen und Methoden eines Objekts zugreifen
‚ Bevor einer Variable eines Objekts ein Wert zuge-
kann.
wiesen wird, muss geprüft werden ob der Wert im
Kontext des Programms sinnvoll ist.
‚ public: Variablen und Methoden mit dem
public Zugriffsoperator sind öffentlich sicht- ‚ Dabei kann sowohl der lesende als auch der schrei-
bar. Andere Objekte haben uneinge- bende Zugriff auf eine Variable durch Properties ge-
schränkten Zugriff auf diese Elemente. steuert werden.

‚ protected: Variablen und Methoden mit Codebeispiel: [Link]


dem protectd Zugriffsoperator sind ge- 1 // ----------------------------------------
schützt sichtbar. Objekte der selben Klasse 2 // Klasse: [Link]
bzw. vererbter Klassen haben Zugriff auf die 3 // ----------------------------------------
Elemente des Objekts. 4 public class Point{
‚ private: Variablen und Methoden mit dem 5 // Variablendefinition
private Zugriffsoperator sind nicht sichtbar. 6 private int _x;
7 // Properties
8 public X {
9 // Lesender Zugriff
Codebeispiel: [Link] 10 get { return _x; }
1 // ---------------------------------------- 11 // Schreibender Zugriff
2 // Klasse: [Link] 12 set { _x = value; }
3 // ---------------------------------------- 13 }
4 public class Point{private int _x;} 14 }
5 15
6 public class Programm { 16 public class Programm {
7 public static void Main(String[] args){ 17 public static void Main(String[] args){
8 Point p = new Point(); 18 Point p = new Point();
9 19 // Schreibender Zugriff mit Property
10 // Achtung Fehler: Kein Zugriff auf 20 p.X = 7;
11 // die Variable _x 21 // Lesender Zugriff mit Property
12 p._x = 7; 22 [Link](p.X)
13 } 23 }
14 } 24 }

9
Softwareentwicklung

Codebeispiel: [Link] 1.3.5 Klassenelement: Konstruktor


1 // ----------------------------------------
2 // Klasse: [Link] L Konstruktor
3 // ----------------------------------------
4 public class Point{ Ein Konstruktor ist eine Methode, die automa-
5 // Variablendefinition tisch beim Erzeugen eines Objekts aufgerufen
6 private int _x; wird. Konstruktoren werden verwendet um die
7 private int _y; Variablen eines Objekts zu initialisieren.
8

9 // Properties
Erklärung: Konstruktor
10 public X {
11 // Lesender Zugriff ‚ Ein Konstruktor hat den gleichen Bezeichner wie die
12 get { return _x; } Klasse, ist jedoch eine Methode ohne Rückgabewert.
13
‚ Eine Klasse kann mehrere Konstruktoren besitzten.
14 // Schreibender Zugriff mit Pruefung Wird für eine Klasse kein Konstruktor definiert,
15 set { stellt das System automatisch einen parameterlosen
16 if(value < 0) Konstruktor zur Verfügung.
17 throw new ArgumentException();
18 _x = value; Codebeispiel: [Link]
19 } 1 // ----------------------------------------
20 } 2 // Klasse: [Link]
21
3 // ----------------------------------------
22 public Y { 4 public class Point {
23 // Lesender Zugriff 5
24 get { return _y; } 6 private int _x;
25
7 private int _y;
26 // Schreibender Zugriff mit Pruefung 8
27 set { 9 public X {
28 if(value < 0) 10 get { return _x; }
29 throw new ArgumentException(); 11 set { _x = value; }
30 _y = value; 12 }
31 } 13
32 } 14 public Y {
33
15 get { return _y; }
34 // Konstruktor 16 set { _y = value; }
35 public Point(){} 17 }
36
18
37 } 19 // Defaultkonstruktor
38
20 public Point(){}
39 public class Programm { 21
40
22 // Konstruktor
41 public static void Main(String[] args){ 23 public Point(int x, int y){
42 Point p = new Point(); 24 X = x;
43 p.X = 7; 25 Y = y;
44 // Achtung Fehler: Es koennen nur 26 }
45 // positive Werte zugewiesen werden 27 }
46 p.X = -13; 28
47 } 29 ...
48
30 public static void Main(String[] args){
49 } 31

32 }

10
© Paul Panhofer

Abbildung 4. Instanzieren eines Objekts

1 // ---------------------------------------- Erklärung: Methoden


2 // Klasse: [Link] ‚ Die Methodendefinition wird innerhalb der Klas-
3 // ---------------------------------------- senimplementierung vorgenommen. Die Methoden
4 public class Programm { eines Objekts haben damit Zugriff auf die Variablen
5
des Objekts.
6 public static void Main(String[] args){
7 // Aufruf des parameterlosen Konstru- ‚ Methoden können nur im Kontext eines Objekts auf-
8 // ktors der Point Klasse. gerufen werden. Zum Aufruf einer Methode wird der
9 Point p = new Point(); Punktoperator verwendet.
10 // Ausgabe von _x und _y. Beide
Codebeispiel: [Link]
11 // Werte sind nicht initialisiert.
12 [Link](p.X, p.Y); 1 // ----------------------------------------
13
2 // Klasse: [Link]
14 // Aufruf des parametrisierten Kon- 3 // ----------------------------------------
15 // struktors der Point Klasse 4 public class Point {
5
16 Point p2 = new Point(3,4);
17 // _x und _y werden mit den Werten 6 private int _x;
18 // 3 und 4 initialisiert. 7 private int _y;
8
19 [Link](p2.X, p2.Y);
20 } 9 public Point(int x, int y){
21
10 _x = x;
22 } 11 _y = y;
12 }
13
❑ 14 public void Scale (int scale){
15 _x = _x * scale;
1.3.6 Klassenelment: Methode 16 }
17 }
18 ...
L Methode 19 public static void Main(String[] args){
In der objektorientierten Programmierung 20 Point p = new Point(4,5);
spielen Methoden eine zentrale Rolle. 21 // Methodenaufruf
22 [Link](3);
Sie bestimmen das Verhalten von Objekten 23 }
und somit das Verhalten des gesamten Pro-
gramms.

11
Softwareentwicklung

Erklärung: Methodendefinition 1.4. Vererbung


‚ Bei der Methodendefinition können mehrere Modi-
fier angegben werden. Der Zugriffsoperator ist einer
dieser Modifier. L Vererbung

‚ Als nächstes wird der Datentyp des Rückgabewerts Vererbung ist eines der grundlegenden Kon-
der Methode definiert. zepte der Objektorientierung.

‚ Dem Datentyp folgt der Methodenname und eine Das Konzept der Vererbung erlaubt es das Ver-
Klammernpaar, in dem sich die optionale Parame- halten einer Klasse auf eine andere Klasse zu
terliste2 befindet. übertragen.

‚ Die Anweisungen, welche das Verhalten der Metho-


Die Vererbung etabliert eine ist ein Beziehung zwi-
de vorgeben, stehen im Methodenrumpf innerhalb
schen 2 Klassen.
der beiden geschweiften Klammern.

Syntax: Methodendefinition 1.4.1 Fallbeispiel: Person


1 // ---------------------------------------- Das Konzept der Vererbung soll anhand eines Beispiels
2 // Syntax: Methodendefinition gezeigt werden.
3 // ----------------------------------------
Codebeispiel: [Link]
4 Modifier Datentyp Methodenname
(Parameterliste) { 1 // ----------------------------------------
5 Anweisungen; 2 // Basisklasse: [Link]
6 } 3 // ----------------------------------------
7
4 public class Person{
5
8 public Integer Transform (Point p){
9 _x += p._x; 6 // Variablen
10 _y += p._y; 7 protected String firstName;
11 } 8 protected String lastName;
9

10 // Properties

11 public String FirstName (get; set;)
12 public String LastName (get; set;)
1.3.7 this Referenz 13

14 // Konstruktor
15 public Person(
L this Referenz 16 String firstName,
Die this Referenz ist ein Verweis auf die Spei- 17 String lastName
cheradresse des Objekts. 18 ){
19 [Link] = firstName;
20 [Link] = lastName;
Erklärung: this Referenz 21 }
‚ Mit dem this Schlüsselwort hat man Zugriff auf die 22

Methoden und Variablen einer Klasse. 23 //Methoden


24 public String Info(){
❑ 25 return $"name: {lastName} {firstName}";
26 }
27

28 }
29 ...
30 public static void Main(String[] args){
2 Person p = new Person("Jonas","Nagi");
Das Klammernpaar muss in jedem Fall angegeben 31

werden, auch wenn eine leere Parameterliste verwendet 32 [Link]([Link]());


wird 33 }

12
© Paul Panhofer

1 // ---------------------------------------- 1.4.2 Konzept: Vererbung


2 // Subklasse: [Link]
3 // ----------------------------------------
4 // Die Klasse Student ist eine Subklasse  Basisklasse
5 // der Klasse Person. Damit erbt sie das Die Basisklasse gibt ihr Verhalten an die Sub-
6 // Verhalten der Person Klasse klassen weiter. Eine Basisklasse kann eine be-
7 public class Student : Person { liebige Zahl von Subklassen haben.
8

9 private String studentCode;


10  Subklasse
11 public String StudentCode ( Subklassen erben das Verhalten ihrer Basisklas-
12 get; set; sen. Die Subklasse hat Zugriff auf alle Varibalen
13 ) und Methoden der Basiklasse die nicht private
14
sind.
15 // Der Student Konstruktor ruft ueber das
16 // base Schluesselwort automatisch den Kon- Subklassen und Basisklassen stehen in einer ist
17 // struktor der Person Klasse auf. ein Beziehung zueinander.
18 public Student (
19 String firstName,
Erklärung: Vererbung
20 String lastName,
21 String studentCode ‚ Die vererbende Klasse wird auch als Basisklasse be-
22 ) : base (firstName, lastName){ zeichnet, die erbende als Subklassen.
23 [Link] = studentCode; ‚ Mithilfe der Vererbung können Eigenschaften und
24 } Methoden einer übergeordneten Klasse auf andere
25 Klassen vererbt werden.
26 }
27

28 // ----------------------------------------
29 // Subklasse: [Link] 1.4.3 Abstrakte Klassen
30 // ----------------------------------------
31 public class Programm { Abstrakte Klassen sind Klassen die in ihrer Klassende-
32 finition das Schlüsselwort abstract enthalten.
33 public static void Main(String[] args){
34 // Ein Student Objekt hat Zugriff auf Erklärung: Absrakte Klassen
35 // das Verhalten der Person Klasse. ‚ Abstrakte Klassen werden gerne als Basisklassen für
36 Student j = new komplexe Vererbungshierarchien verwendet.
Student("Jonas","Nagi",
‚ Das besondere an abstrakten Klassen ist, dass für
"e9725248");
sie keine Instanzen erstellt werden können.
37

38 [Link] = "Joni";
Codebeispiel: [Link]
39 [Link] = "Nagelmaier";
40
1 // ----------------------------------------
41 // Als Datentyp fuer ein Student Objekt 2 // Basisklasse: [Link]
42 // kann auch Person angegeben werden 3 // ----------------------------------------
43 Person t = new 4 public abstract class Person{
Student("Tobias","Haid","e9845323"); 5 ...
44 [Link]([Link]()); 6 }
7
45 }
46
8 public class Student : Person {
9
47 }
10 }


13
Softwareentwicklung

1.5. Speicherverwaltung 1.5.2 Datenstruktur Heap


Der Heap besitzt im Gegensatz zum Stack keine
Im Speicher eines Rechners werden die Daten3 von
Struktur.
Programmen verwaltet. Zur Verwaltung der Daten
werden dabei 2 Datenstrukturen verwendet: Stack und Der Heap im Speicher wird verwendet um die Ob-
Heap. jekte in Programmen zu verwalten.

Im allgemeinen bezeichnen Stack und Heap Teile des


Erklärung: Datenstruktur Heap
Speichers die einem Programm auf Betriebssysteme-
bene bei der Ausführung zugeteilt werden. ‚ Der Heap ist ein unstrukturierte Bereich des Spei-
chers zur Verwaltung von Programmdaten.

‚ Während der Stack von der Größe her begrenzt ist,


1.5.1 Datenstruktur Stack kann der Heap anwachsen bis die Speichergrenze
Der Name Stack deutet bereits an, dass Daten struk- auf Prozessebene erreicht ist.
turiert übereinander gespeichert werden. ‚ Im Gegegensatz zum Stack kann der Heap nicht so
einfach verwaltet werden, was ihn im Einsatz signi-
Erklärung: Datenstruktur Stack fikant langsamer macht.
‚ Bei einem Stack werden Daten übereinandergesta-
pelt.
‚ Für den Zugriff auf den Heap werden Zeiger ver-
wendet.
‚ Wenn die Daten wieder freigegeben werden, wer-
den Sie von oben nach unten wieder entfernt. Dieses ❑
Prinzip nennt sich auch LIFO (Last in, First out).

‚ Der Stack kann, bedingt durch seine Struktur, sehr


effizient verwaltet werden, weshalb Stackoperatio-
nen sehr schnell sind.

‚ Der Stack wird dabei verwendet um die Werte von


1.5.3 Programmartefakt Zeiger
Variablen einfacher Datentypen4 gespeichert.
L Programmartefakt Zeiger
‚ Objekte können nicht auf dem Stack gespeichert
werden. Für Objekte wird lediglich ein Verweis auf Ein Zeiger speichert im Gegensatz zu einer ge-
den Heap gespeichert. wöhnlichen Variable keinen konkreten Wert -
z.b.: int k = 3; - sondern einen Verweis auf ei-
❑ ne Speicheradresse im Heap.

Zeiger werden auch als Objektreferenz bzw.


Referenzvariable bezeichnet.

Erklärung: Programmartefakt Zeiger


‚ Bei der Definition eines Objekts wird auf dem Stack
nicht das Objekt selbst sondern ein Verweis auf das
Objekt im Heap gespeichert.

‚ Die Variable speichert damit nicht das Objekt selbst


sondern nur einen Verweis auf das Objekt. Solche
Variablen werden auch als Referenzvariablen be-
zeichnet.

‚ Zeiger sind dabei direkt mit dem Datentyp assoziert,


die das Objekt hat, auf das sie verweisen.

3 ❑
Variablen, Objekte
4
int, long, short, char, byte, float, double

14
© Paul Panhofer

Abbildung 5. Speicherverwaltung: Stack vs. Heap

1.6. Implizite Vererbung 1.6.2 Methode: ToString


Die ToString Methode konvertiert ein Objekt in seine
Zeichenfolgendarstellung.
L Implizite Vererbung
Syntax: ToString
Jede Klasse die nicht explizit von einer ande-
ren Klasse erbt, erbt implizit von der Klasse Ob- 1 // ----------------------------------------
ject. 2 // Syntax: ToString
3 // ----------------------------------------
Damit stehen jedem Objekt die Methoden 4 public string ToString(){};
der Klasse Object zur Verfügung. 5

6 public class Point{


7

8 private int _x;


1.6.1 Verhalten der Object Klasse
9

Die Object Klasse stellt für die übrigen Klassen eine 10 private int _y;
Grundimplementierung bereit. 11

12 public Point(int x, int y){


Analyse: Verhalten der Object Klasse 13 this._x = x;
‚ Das Verhalten der Object Klasse stellt Methoden zur 14 this._y = y;
Speicherverwaltung bzw. zur Objektidentifikation
15 }
16
bereit.
17 public override string ToString(){
‚ In der Regel ist das Verhalten der Object Klasse für 18 return $"x: {_x} y: {_y}";
andere Klassen zu allgemein. Durch das Überschrei- 19 }
ben der Methoden der Object Klasse kann auf die 20

Besonderheiten der Klassen eingegangen werden. 21 }


15
Softwareentwicklung

1.6.3 Methode: Equals Die Konzepte der Referenzgleichheit und Wertegleich-


heit existieren in selber Form in der Sprachwissen-
Die Equals Methode testet 2 Objekte auf Gleichheit.
schaft.
Analyse: Gleichheit von Objekten Das Gleiche - Wertegleichheit - bedeutet, dass zwei
‚ Zum Vergleich von 2 Werten auf Gleichheit wird in unterschiedliche Dinge sich aufs Haar gleichen,
der Regel der == Operator verwendet. während dasselbe - Referenzgleichheit - bedeutet,
dass diese identisch sind.
‚ Für einfache Datentypen ist diese Vorgangsweise
auch vollkommen ausreichend. Syntax: Equals
1 // ----------------------------------------
‚ Für Objekte unterscheidet man jedoch 2 Formen der
2 // Syntax: Equals
Gleichheit: Referenzgleichheit und Wertegleich-
3 // ----------------------------------------
heit.
4 public bool Equals (object obj){...}
‚ Referenzgleichheit: Wir sprechen bei Objekten von 5

Referenzgleichheit wenn 2 Objektreferenzen auf das- 6 // ----------------------------------------


selbe Objekt im Speicher verweisen. Referenzgleich- 7 // Implementierung: Point
heit wird für Objekte mit der Hilfe des == Operators 8 // ----------------------------------------
geprüft. 9 public class Point {
10
‚ Wertegleichheit: Für 2 Objektreferenzen besteht
11 private int _x, _y;
Wertegleichheit wenn wenn der Zustand der Objekte
12
gleich ist.
13 public Point(int x, int y){
Codebeispiel: Referenzgleichheit 14 this._x = x;
1 // ---------------------------------------- 15 this._y = y;
2 // Referenzgleichheit vs Wertegleichheit 16 }
3 // ---------------------------------------- 17

4 public class UnitTest { 18 // Ueberschreiben der von Object implizit


5 [Test] 19 // geerbten Equals Methode
6 public void TestReferenceEqulity() { 20 public override bool Equals(object obj) {
7 Point p1 = new Point(3,4); 21 //Pruefung ob obj null ist oder nicht
8 Point p2 = new Point(5,6); 22 if (ReferenceEquals(null, obj))
9 Point p3 = p1; 23 return false;
10 Point p4 = new Point(5,6); 24 //Pruefung ob es sich um dasselbe
11 25 //Objekt handelt
12 [Link](p1 == p2); 26 if (ReferenceEquals(this, obj))
13 [Link](p1, p2); 27 return true;
14 28 //Pruefung ob beide Objekte denselben
15 [Link]([Link](p2)); 29 //Datentyp haben
16 [Link](p1, p2); 30 if ([Link]() != [Link]())
17 31 return false;
18 [Link](p2 == p4); 32

19 [Link](p2, p4); 33 return Equals((Point) obj);


20 34 }
21 [Link]([Link](p4)); 35

22 [Link](p2, p4); 36 // Pruefen auf Wertegleichheit zwischen


23 37 // Punkten
24 [Link](p1 == p3); 38 protected bool Equals(Point other) {
25 [Link](p1, p3); 39 return _x == other._x &&
26 [Link]([Link](p3)); 40 _y == other._y;
27 [Link](p1, p3); 41 }
28 } 42

29 } 43 }

16
© Paul Panhofer

Abbildung 6. Definitionsebenen

Codebeispiel: Wertegleichheit 1.7. Anweisungsblock


1 // ----------------------------------------
2 // Wertegleichheit Ein Programm besteht aus Anweisungen. Über An-
3 // ---------------------------------------- weisungen werden Variablen deklariert, Werte zugewie-
4 public class UnitTest { sen, Bedingungen definiert usw.
5 [Test]
6 public void TestEqulity(){ 1.7.1 Anweisungsblock
7 Point p1 = new Point(3,4);
Eine Anweisung kann aus einer einzelnen Codezeile,
8 Point p2 = new Point(3,4);
die mit einem Semikolon endet, oder aus einer Reihe
9
von einzeiligen Anweisungen in einem Block, bestehen.
10 Point p3 = p1;
11 Point p4 = p3;
12 Point p5 = p2; L Anweisungsblock
13
Ein Anweisungsblock besteht aus in ge-
14 [Link](p1, p2); schweiften Klammern eingebetteten Anwei-
15 [Link](p1 != p2); sungen.
16

17 [Link](p1, p2); In einem Anweisungsblock können andere


18 Anweisungsblöcke eingebettet werden.
19 [Link](p1 == p3);
20 [Link](p1 == p4);
Erklärung: Anweisungsblock
21

22 [Link](p1, p3); ‚ Ein Anweisungsblock wird als einzelne Anweisung


23 [Link](p1, p4); durch den Compiler ausgeführt.
24 } ‚ In einem Anweisungsblock können Variablen defi-
25 } niert werden. Solche Variablen gelten jedoch nur in-
nerhalb des Blocks.
❑ ❑

17
Softwareentwicklung

1.7.2 Gültigkeitsbereich von Variablen 1.7.3 Fallbeispiel: Gültigkeitsbereich


Variablen gelten in jenem Block in dem sie definiert
Codebeispiel: [Link]
werden.
1 // ----------------------------------------
Erklärung: Gültigkeitsbereich von Variablen 2 // Klasse: [Link]
3 // ----------------------------------------
‚ Anweisungsblöcke können inneinander verschachtelt
4 public class Point{
sein, das heißt: ein Block kann einen anderen Block
5
enthalten. Der innere Block ist dann wieder ein ei-
6 //Variablendeklaration im Klassenblock
gener Gültigkeitsbereich.
7 private int _x;
‚ Ein Block übernimmt dabei alle Deklarationen um- 8 private int _y;
gebender Gültigkeitsbereiche. 9

10 public Point(int x, int y){


‚ Für Klassen unterscheidet man dabei 3 Typen von
11 this._x = x;
Gültigkeitsbereichen: Klassenblock, Methodenblock,
12 this._y = y;
Anweisungsblock.
13 }
14

 Klassenblock 15 public Point(){


16
Der Gültigkeitsbereich einer Klasse wird als
17 }
Klassenblock bezeichnet. Alle auf Klassenebe-
18
ne definierten Variablen sind in eingebetteten
19 ...
Blöcken gültig.
20

21 public int CalculateDistance(Point p){


2 Methodenblock 22 //Variablendeklaration im Methodenblock
23 int distance = 0;
Der Gültigkeitsbereich einer Methode wird 24 distance = ...
als Methodenblock bezeichnet. Variablen des 25
Methodenblocks gelten nur in der Methode. 26 return distance;
27 }
Variablen in einem Methodenblock die den-
28
selben Namen haben wie Variablen im Klas-
29 public override bool Equals(object obj) {
senblock, überschatten alle anderen Varia-
30 //Pruefung ob obj null ist oder nicht
blen.
31 if (ReferenceEquals(null, obj))
32 return false;
3 Anweisungsblock 33 //Pruefung ob es sich um dasselbe
34 //Objekt handelt
Der Gültigkeitsbereich einer Anweisung wird
35 if (ReferenceEquals(this, obj))
als Anweisungsblock bezeichnet.
36 return true;
37 //Pruefung ob beide Objekte denselben
❑ 38 //Datentyp haben
39 if ([Link]() != [Link]())
40 return false;
41

42 return Equals((Point) obj);


43 }
44

45 }

18
© Paul Panhofer

1.8. Klassenobjekt 1 // ----------------------------------------


2 // Instanzenzaehler
3 // ----------------------------------------
1.8.1 Klassenobjekt vs. Objekt 4 private static int COUNTER = 0;
5
Klassen werden definiert, um Objekte zu erzeugen.
Klassen sind dabei vergleichbar mit einer Backform 6 public static int COUNTER_VALUE (){
die zur Herstellung von Plätzchen - den Objekten - 7 return COUNTER;
dient. 8 }
9 }
Erklärung: Klassenobjekt 10

‚ Eine Klasse und ihre Objekte stellen unterschiedli- 11 // ----------------------------------------


che Konzepte dar, genauso wie die Backform und 12 // Unittest: Instanzenzaehler
das Plätzchen. 13 // ----------------------------------------
14 public class PointerTest{
‚ Eine Backform hat Merkmale, die nicht mit den
15
Plätzchen geteilt werden. Zum Beispiel besteht ei-
16 [Test]
ne Backform aus Blech und besitzt scharfe Kanten.
17 public void TestCounter(){
‚ Zur Beschreibung der Eigenschaften und des Verhal- 18 Point p1 = new Point(3,4);
tens der Klasse - der Backform - wird das Klassen- 19 Point p2 = new Point(0,1);
objekt verwendet. 20 Point p3 = new Point(7,7);
21

22 [Link](3,
L Klassenobjekt Point.COUNTER_VALUE());
23 }
Das Klassenobjekt beschreibt das Verhalten
24
und den Zustand einer Klasse. Dazu wird für
25 }
die Variablen und Methoden des Klassenob-
jekts der static Modifikator verwendet. Das
Klassenobjekt selbst wird dabei über den Na- ❑
men der Klasse referenziert.

Egal wie viele Objekte einer bestimmten Klas-


L | 
se erzeugt werden, es gibt immer nur ein Klas-
senobjekt für jede Klasse. 1.8.2 Motivation: Klassenobjekt
Das Klassenobjekt wird in der Objektorientierten Pro-
Codebeispiel: Instanzenzähler grammierung in unterschiedlichen Szenarien einge-
1 // ---------------------------------------- setzt.
2 // Instanzenzaehler Erklärung: Klassenobjekt
3 // ----------------------------------------
4 // Fuer die Point Klasse soll ein Instanz-
‚ Das Klassenobjekt kann zur Verwaltung systemwei-
ter Konstanten bzw. Werte verwendet werden. Sta-
5 // zaehler programmiert werden.
tische Werte bzw. Konstanten werden in diesem Fall
6 public class Point{
als globale Variable bzw. globale Konstante be-
7
zeichnet.
8 public int _x, _y;
9 ‚ Verhalten das keiner spezifischen Klasse zugeord-
10 public Point(int x, int y){ net werden kann, kann in Klassenobjekten gekapselt
11 this._x = x; werden. Es wird damit eine beschränkte Funktions-
12 this._y = y; bibliothek geschaffen.
13 COUNTER++;
14 }

19
Softwareentwicklung

Bei unreflektiertem Gebrauch des Klassenobjekts 1.9. Interface


kann es jedoch zu einer Unterwanderung des Ob-
jektorientierten Konzepts kommen.
L Interface
L |  Eine Schnittstelle legt einen Vertragsrahmen
fest, den implementierenden Klassen erfüllen
Codebeispiel: Klassenobjekt müssen.
1 // ----------------------------------------
2 // Klassenobjekt: Math Dazu definiert das Interface eine Menge
3 // ---------------------------------------- von Methodensignaturen, die die gewünsch-
4 // Die Math Klasse ist als reines Klassen- te Klasse implementieruen muss.
5 // objekt konzipiert.
6
Die Schnittstelltenprogrammierung ist einer der
Grundpfeiler der objektorientierten Programmie-
7 // Auszug aus der Math Klasse
8 public class Math { rung.
9

10 // Globale Konstanten 1.9.1 Interne Schnittstelle


11 // Das Schluesselwort const beinhaltet
12 // automatisch das Schluesselwort static Ein Objekt wird beschrieben durch seinen Zustand und
13 public const double E = 2.718281828459; sein Verhalten.
14
Erklärung: Interne Schnittstelle
15 public const double PI = 3.14159265358;
‚ Das Verhalten eines Objekts wird durch die Metho-
16
den seiner zugehörigen Klasse beschrieben.
17 // Globale Variablen
18 private static double RoundLimit = 1e16d; ‚ Für Methoden unterscheidet man zwischen dem Me-
19 thodenkopf und dem Methodenkörper. Der Metho-
20 // Globales Verhalten denkopf wird dabei auch als Methodensignatur, der
21 public static int Abs(int value){ Methodenkörper als die Methodenimplementierung
22 if (value < 0){ bezeichnet.
23 value = (short)-value;
‚ Beim Zugriff auf die Methode eines Objekts muß
24
die Signatur der Methode bekannt sein. Die Kenn-
25 return value;
tins der Implementierung der Methode ist in diesem
26 }
Zusammenhang irelavant.
27 }
28 ‚ Die Signaturen der Methoden eines Objekts werden
29 // ---------------------------------------- als die interne Schnittstelle des Objekts bezeichnet.
30 // Unittest: Math

31 // ----------------------------------------
32 public class MathTest{
33 1.9.2 Externe Schnittstelle
34 public void ClassObjectTest(){
Um Methoden auf Objekten aufrufen zu können muss
35 // Zur Verwendung des Klassenobjekt
die interne Schnittstelle der Objekte bekannt sein.
36 // muss keine Instanz erstellt werden.
37 // Das Klassenobjekt wird ueber den Erklärung: Externe Schnittstelle
38 // Namen der Klasse referenziert.
39 [Link](2.718281828459,
‚ Zur Trennung der Schnittstelle von der Implemen-
tierung einer Klasse, kann die Schnittstelle der Klas-
Math.E);
se explizit definiert werden.
40 }
41 ‚ Explizit definierte Schnittstellen werden auch als
42 } Externe Schnittstelle bzw. das Interface der Klasse
bezeichnet.
❑ ❑

20
© Paul Panhofer

Abbildung 7. Interne Schnittstelle einer Klasse

1.9.3 Interface 1.9.4 Implementierung vs. Vererbung


Ein Interface definiert einer Menge von Methodensi- Die Prinzipien der Vererbung bzw. Implementierung
gnaturen bzw. Properties. stellen 2 unterschiedliche Konzepte in der Program-
mierung dar.
Erklärung: Interface
‚ Eine Klasse kann ein oder mehrere Interfaces im- Analyse: Implementierung vs. Vererbung
plementieren. Der Typ einer Klasse kann in diesem
Fall auf mehrere Interfaces verdichtet werden.
‚ Im Rahmen der Vererbung wird das Verhalten der
Basisklasse an die Subklasse vererbt. In einer Sub-
‚ Ein Interface definiert welche Properties bzw. Me- klassen kann damit auf das Verhalten der Basisklas-
thoden eine Klasse haben muss, sollte die Klasse das se zurückgegriffen werden.
Interface implementieren.
Zwischen den Subklassen und der Basisklasse gilt
‚ Objekte der Klasse gehen damit einen Vertragsrah- eine ist ein Beziehung.
men ein. Für jede im Interface definierte Methoden-
signatur muss das Objekt eine Implementierung be- ‚ Klassen die ein Interface implementieren gehen einen
sitzen. Contract ein: Für jede im Interface enthaltene Me-
thodensignatur muss die Klasse eine Implementie-
‚ Interfaces werden verwendet um die Schnittstelle ei- rung definieren. Zwischen der implementierenden
ner Anwendung von ihrer Implementierung zu tren- Klasse und dem Interface liegt ein Vertragsrahmen
nen. vor, es wird kein Verhalten weitergegeben.

21
Softwareentwicklung

1.9.5 Definition eines Interfaces 1 // ----------------------------------------


2 // Fallbeispiel: Interface
Ein Interface definiert eine Menge von Methodensigna- 3 // ----------------------------------------
turen bzw. Properties. 4 public class Programm{
5
Codebeispiel: Interfacedefinition 6 public static void Main(String[] args){
1 // ---------------------------------------- 7 List<IQuackBehavior> ducks = new
2 // Definition: Interface List<IQuackBehavior>();
3 // ---------------------------------------- 8

4 public interface IQuackBehavior{ 9 [Link](new RedheadDuck());


5 // Methodensignatur 10 [Link](new MarbledDuck());
6 /* 11 [Link](new DuckDecoy());
7 * Jede in im Interface definierte 12 [Link](new RubberDuck());
8 * Methodensignatur hat den public 13

9 * Zugriffsoperator 14 foreach(var duck in ducks){


10 */ 15 [Link]([Link]());
11 string Quack(); 16 }
12 } 17 }
13 18

14 // IQuackBehavior Implementation 19 }
15 public class RedheadDuck : IQuackBehavior{ 20

16 21 > Consolenausgabe
17 public string Quack(){ 22

18 return "... quack quack"; 23 ... quack quack


19 } 24 ... qua qua qua
20 25 ... QUACK QUACK
21 } 26 ... Squeeze
22

23 // IQuackBehavior Implementation

24 public class MarbledDuck : IQuackBehavior{
25

26 public string Quack(){ 1.9.6 Analyse: Interface


27 return "... qua qua qua";
28 } Ein Interface legt fest über welche Methoden eine Klas-
29
se, die die Schnittstelle implementiert, verfügen muss.
30 }
31
Analyse: Interface
32 // IQuackBehavior Implementation ‚ Interfaces werden verwendet, um Gemeinsamkeiten
33 public class RubberDuck : IQuackBehavior{ die mehreren Klassen zugrunde liegen, in einem se-
34 paraten Artefakt zu kapseln.
35 public string Quack(){
‚ Objekte der implementierenden Klasse sind wie bei
36 return "... squeeze";
der Vererbung dann gleichzeitig auch Objekte des
37 }
Interfaces.
38

39 } ‚ Interfaces werden verwendet, um die Schnittstelle ei-


40 ner Klasse von deren Implementierung zu trennen.
41 // IQuackBehavior Implementation Damit kann die Schnittstelle unabhängig von der
42 public class DuckDecoy : IQuackBehavior{ Implementierung entwickelt werden.
43
‚ Generell werden Interfaces dazu verwendet um Ab-
44 public string Quack(){
hängigkeiten zwischen Klassen zu vermeiden.
45 return "... QUACK QUACK";
46 } ❑
47 }

22
© Paul Panhofer

1.9.7 Objektorientiertes Design 1.9.8 Fallbeispiel: DuckSimulator


Gutes Objektorientiertes Design erlaubt es komplexe Zur Veranschaulichung guten Objektorientierten Desi-
Probleme auf einfache Weise zu lösen. gns wollen wir ein einfaches Programm schreiben. Das
Programm wird dabei schrittweise um neue Features
Erklärung: Objektorientiertes Design erweitert, ohne dabei bereits bestehenden Code zu än-
‚ Unter Objektorientiertem Design versteht man dern.
bestimmte Programmiertechniken. Werden diese Codebeispiel: Ducksimulator
Programmiertechniken eingehalten, sind Program-
1 // ----------------------------------------
me klar strukturiert und einfach wartbar.
2 // Fallbeispiel: DuckSimulator - [Link]
‚ Eines der wichtigsten Prinzipien der Objektorientie- 3 // ----------------------------------------
rung ist es Abhängigkeiten5 zwischen Objekten zu 4 public class Programm{
vermeiden. Abhängigkeit zwischen Objekten können 5 public static void Main(String[] args){
mit der Hilfe von Interfaces aufgelöst werden. 6 List<IQuackBehavior> ducks = new
List<>();
‚ Bestehen keine Abhängigkeiten zwischen den Objek-
7
ten eines Programms, kann das Programm einfach
8 [Link](new ReadHeadDuck());
erweitert werden ohne bereits bestehende Klassen
9 [Link](new MarbledDuck());
ändern zu müssen.
10 [Link](new RubberDuck());
‚ Dieses Prinzip der Objektorientierten Programmie- 11 [Link](new DuckDecoy());
rung ist so wichtig dass es einen eignen Namen be- 12

kommen hat: Open Closed Prinzip. 13 DuckSimulator sim = new


DuckSimulator();
❑ 14

15 [Link](ducks);
16 }
17 }
5
Objekte stehen in Abhängigkeit zueinander wenn sie
die Methoden anderer Klassen aufrufen.

23
Softwareentwicklung

1 // ---------------------------------------- 51 public class Goose : IHonkBehaviour{


2 // Klasse: DuckSimulator - [Link] 52 public string Honk(){
3 // ---------------------------------------- 53 return "honk honk";
4 public class DuckSimulator { 54 }
5 55 }
6 public void Simulate(List<IQuackBehavior> 56
ducks){ 57 public class Programm{
7 foreach(IQuackBehaviour duck in ducks){ 58 public static void Main(String[] args){
8 [Link]([Link]()); 59 List<IQuackBehavior> ducks = new
9 } List<>();
10 } 60

11 61 [Link](new ReadHeadDuck());
12 } 62 [Link](new MarbledDuck());
13 63 [Link](new RubberDuck());
14 // ---------------------------------------- 64 [Link](new DuckDecoy());
15 // Fallbeispiel: DuckSimulator - [Link] 65 [Link](new HonkAdapter(new
16 // ---------------------------------------- Goose()));
17 // Wir wollen unser Programm nun um etwas 66

18 // erweitern. Es sollen nicht nur Ducks 67 DuckSimulator sim = new


19 // in unserem Simulator verwendet werden DuckSimulator();
20 // sondern auch Gaense. 68

21 69 [Link](ducks);
22 // Das Problem ist dass Gaense ein andere 70 }
23 // Schnittstelle haben als Enten. Wir 71 }
24 // muessen einen Weg finden die Schnitt- 72

25 // stelle der Gaense kompatibel zu machen 73 // ----------------------------------------


26 // mit der Schnittstelle der Enten. 74 // Fallbeispiel: DuckSimulator - [Link]
27 75 // ----------------------------------------
28 // Um das zu erreichen wird ein sogenannter 76 // Das Programm soll nun um folgende Features
29 // Adapter verwendet. 77 // erweitert werden: Immer wenn die Quack()
30 78 // Methode aufgerufen wird soll das mitge-
31 // (siehe Entwurfsmuster: Adapter) 79 // zaehlt werden.
32 80

33 public interface IHonkBehavior{ 81 // Zusaetzlich soll vor der Ausgabe jedesmal


34 public string Honk(); 82 // noch die Zeichenkette "output" auszugeben.
35 } 83

36 84 // Hinweise: Bestehende Klassen duerfen


37 public class HonkAdapter : IQuackBehavior{ 85 // nicht veraendert werden.
38 86

39 private IHonkBehaviour _honkable; 87 // Zur Loesung des Problems wird das Entwurfs-
40 88 // muster Dekorator verwendet.
41 public HonkAdapter(IHonkBehavior 89

honkable){ 90 public class OutputDecorator :IQuackBehavior{


42 this._honkable = honkable; 91 private IQuackBehavior _quackable;
43 } 92

44 93 public OutputDecorator(IQuackBehavior q){


45 public string Quack(){ 94 this._quackable = q;
46 return this._honkable.Honk(); 95 }
47 } 96 public void Quack(){
48 97 return "Output: " + _quackable.Quack();
49 } 98 }
50 99 }

24
© Paul Panhofer

100 public class QuackCountDecorator : 138 // ----------------------------------------


IQuackBehavior{ 139 // Fallbeispiel: DuckSimulator - [Link]
101 140 // ----------------------------------------
102 private IQuackBehavoir _quackable; 141 // Das Erzeugen der einzelnen Enten soll
103 142 // nun in eigene Klasse ausgelagert werden.
104 public static int COUNTER = 0; 143

105 144 // Verwenden Sie dazu das Entwufsmuster


106 public QuackCountDecorator(IQuackBehavior 145 // FactoryMethode
quackable){ 146 public interface IDuckFactory{
107 this._quackable = quackable; 147

108 } 148 IQuackBehavior CreateReadHeadDuck();


109 149

110 public string Quack(){ 150 IQuackBehavior CreateMarbledDuck();


111 ++COUNTER; 151

112 return _quackable.Quack(); 152 IQuackBehavior CreateRubberDuck();


113 } 153

114 154 IQuackBehavior CreateDuckDecoy();


115 } 155

116 156 IQuackBehavior CreateGoose();


117 public class Programm{ 157 }
118 public static void Main(String[] args){ 158

119 List<IQuackBehavior> ducks = new 159

List<>(); 160 public class DecoratedDuckFacotry :


120 IDuckFactory{
121 [Link](new OutputDecorator(new 161

QuackCountDecorator(new 162 public IQuackBehavior CreateReadHDuck(){


ReadHeadDuck()))); 163 return new OutputDecorator(new
122 QuackCountDecorator(new
123 [Link](new OutputDecorator(new ReadHeadDuck()));
QuackCountDecorator(new 164 }
MarbledDuck()))); 165

124 166 public IQuackBehavior CreateMarbledDuck(){


125 [Link](new OutputDecorator(new 167 return new OutputDecorator(new
QuackCountDecorator(new QuackCountDecorator(new
RubberDuck()))); MarbledDuck()));
126 168 }
127 [Link](new OutputDecorator(new 169

QuackCountDecorator(new 170 public IQuackBehavior CreateRubberDuck(){


DuckDecoy()))); 171 return new OutputDecorator(new
128 QuackCountDecorator(new
129 [Link](new OutputDecorator(new RubberDuck()));
QuackCountDecorator(new 172 }
HonkAdapter(new Goose())))); 173

130 174 public IQuackBehavior CreateGoose(){


131 DuckSimulator sim = new 175 return new OutputDecorator(new
DuckSimulator(); QuackCountDecorator(new
132 HonkAdapter(new Goose()));
133 [Link](ducks); 176 }
134 } 177 }
135 } 178

136 179

137 180

25
Softwareentwicklung

181 public class Programm{ .


182 public static void Main(String[] args){
183 List<IQuackBehavior> ducks = new
List<>();
184 IDuckFactory factory = new
DecoratedDuckFactory();
185

186 [Link]([Link]());
187 [Link]([Link]());
188 [Link]([Link]());
189 [Link]([Link]());
190 [Link]([Link]());
191

192 DuckSimulator sim = new


DuckSimulator();
193

194 [Link](ducks);
195 }
196 }
197

198 // ----------------------------------------
199 // UnitTest: DuckSimulator - [Link]
200 // ----------------------------------------
201 public class DuckSimulatorUnitTest {
202

203 [Test]
204 public void QuackCountDecoratorTest(){
205 List<IQuackBehavior> ducks = new
List<>();
206 IDuckFactory factory = new
DecoratedDuckFactory();
207

208 [Link]([Link]());
209 [Link]([Link]());
210 [Link]([Link]());
211 [Link]([Link]());
212 [Link]([Link]());
213

214 DuckSimulator sim = new


DuckSimulator();
215

216 [Link](ducks);
217

218 [Link](5,
[Link]);
219 }
220

221 }

26
© Paul Panhofer

. .

27
Softwareentwicklung

2. Collections 2.1. Datenstrukturen

L Datenstrukturen
Eine Datenstruktur ist ein Objekt, welches zur
Speicherung und Organisation von Daten
dient.

Die wohl einfachste Datenstruktur der objektorien-


tierten Programmierung ist das Array.

2.1.1 Grundlagen
Eine Datenstruktur wird als Behälter für andere Ob-
jekte verwendet.
Erklärung: Datenstrukturen
‚ Je nach Datenstruktur werden die enthaltenen Ob-
jekte unterschiedlich strukturiert.
‚ Manche Datenstrukturen erlauben das mehrfache
01. Datenstrukturen 28 Speichern gleicher6 Objekte. Andere Datenstruktu-
ren ordnen Objekte bereits beim Speichern in der
02. Datenstruktur: List 29 Datenstruktur.
‚ Jede Datenstruktur unterstützt dazu unterschiedli-
03. Datenstruktur: Stack 32 che Methoden und Konzepte.

04. Datenstruktur: Queue 35

05. Datenstruktur: Dictionary 37

06. Indexer 40

Analyse: Datenstrukturen
‚ Es ist zu beachten das eine Datenstruktur im Grun-
de nur Elemente vom Stack verwaltet. Datenstruk-
turen verwalten damit keine Objekte im eigentlichen
Sinne sondern deren Objektreferenzen vom Stack.
‚ Dieses Prinzip erlaubt es ein Objekt mit mehre-
ren Datenstrukturen zu verwalten ohne eine Kopie
des Objekts erstellen zu müssen. Es werden ledig-
lich neue Pointer am Stack angelegt die auf dasselbe
Objekt verweisen.
‚ Die Speicherbelastung kann damit gleichzeitig ge-
ring gehalten werden.

6
Wertegleichheit

28
© Paul Panhofer

Seite
Befehl Beschreibung

Add Fügt ein Element am Ende der Liste ein. 29


AddRange Fügt eine Liste von Elementen am Ende der Liste an. 29
Clear Löschte alle Elemente der Liste. 30
Contains Überprüft ob ein bestimmtes Element in der Liste enthalten ist. 30
Insert Fügt ein Element an einem bestimmten Index ein. 30
InsertRange Fügt die Elemente einer anderer Kollection ab einem bestimmten Index an. 30
Remove Entfernt das erste Vorkommen des angegeben Elements aus der Liste. 30
RemoveAt Entfernt das Element am angegebenem Index 30

Abbildung 8. Listenmethoden

2.2. Datenstruktur: List 1 // ----------------------------------------


2 // Method: Add
3 // ----------------------------------------
L Datenstruktur Liste 4 [Test]
Listen weisen starke Änlichkeiten zur Daten- 5 public void TestAdd(){
struktur der Arrays auf. 6 List<Point> points = new List<>();
7 [Link](new Point(3,4));
Wie bei einem Array werden die Elemente se- 8 [Link](new Point(5,6));
quentiell auf dem Stack gespeichert und kön- 9

nen schnell über ihre Position angesprochen 10 [Link](2, [Link]);


werden. Im Gegensatz zum Array kann eine 11 }
Liste eine beliebige Zahl von Elementen ver- 12 }
walten. 13

14 // ----------------------------------------
15 // Syntax: AddRange
2.2.1 Verhalten von Listen 16 // ----------------------------------------
17 // Mit der AddRange Methode kann eine Liste
Bei einer Liste handelt es sich um eine geordnete Da- 18 // von Elmenten an das Ende der Liste ge-
tenstruktur auf die man wie bei Arrays über einen nu- 19 // setzt werden
merischen Index zugreifen kann. Folgende Methoden 20 public void AddRange(List<T> l){...};
werden dabei von der Datenstruktur unterstützt. 21

22 public class ListUnitTest{


Verhalten: Datenstruktur Liste 23 [Test]
1 // ---------------------------------------- 24 public void TestAddRange(){
2 // Syntax: Add 25 List<Point> l1 = new List<>();
3 // ---------------------------------------- 26 [Link](new Point(3,4));
4 // Mit der Add Methode kann ein neues 27 [Link](new Point(5,6));
5 // Element am Ende der Liste eingefuegt 28

6 // werden. 29 List<Point> l2 = new List<>();


7 public void Add(T item){...}; 30 [Link](l1);
8 31

9 // Unittest 32 [Link](2, [Link]);


10 public class ListUnitTest{ 33 }
34 }

29
Softwareentwicklung

1 // ---------------------------------------- 1 // ----------------------------------------
2 // Syntax: Clear 2 // Syntax: Insert
3 // ---------------------------------------- 3 // ----------------------------------------
4 // Mit der Clear Methode werden alle Elemente 4 // Mit der Insert Methode kann ein Element
5 // aus der Liste geloescht. 5 // an einem bestimmten Index in die Liste
6 public void Clear(){...}; 6 // eingefuegt werden. Elemente deren Index
7 7 // groesser bzw gleich dem angegebenem
8 public class ListUnitTest{ 8 // Index ist, werden um eine Stelle nach
9 [Test] 9 // hinten verschoben
10 public void TestClear(){ 10 public void Insert(int index, T elem){...};
11 List<Point> points = new List<>(); 11

12 12 public class ListUnitTest{


13 [Link](new Point(3,4)); 13 [Test]
14 [Link](new Point(3,2)); 14 public void TestInsert(){
15 [Link](new Point(6,4)); 15 List<int> points = new List<>();
16 [Link](new Point(9,3)); 16

17 [Link](new Point(2,6)); 17 [Link](56);


18 18 [Link](3);
19 [Link](); 19 [Link](26);
20 20 [Link](2);
21 [Link](0, [Link]); 21

22 } 22 [Link](4, [Link]);
23 } 23

24 24 [Link](1, 21);
25 // ---------------------------------------- 25

26 // Syntax: Contains 26 [Link](5, [Link]);


27 // ---------------------------------------- 27 [Link](56, points[0]);
28 // Mit der Contains Methode wird geprueft 28 [Link](21, points[1]);
29 // ob ein bestimmtes Element in der Liste 29 [Link](3, points[2]);
30 // enthalten ist. 30 }
31 public bool Contains(T elem){...}; 31 }
32 32

33 // Hinweis: Die Contains Methode prueft auf 33 // ----------------------------------------


34 // Wertegleichheit. Ueberschreiben Sie die 34 // Syntax: Remove
35 // Equals Methode der Elementklasse 35 // ----------------------------------------
36 public class ListUnitTest{ 36 // Mit der der Remove Methode wird das erste
37 [Test] 37 // Vorkommen des uebergebenen Parameters aus
38 public void TestContains(){ 38 // der Liste entfernt.
39 List<Point> points = new List<>(); 39 public bool Remove(T item){...}
40 40

41 [Link](new Point(4,3)); 41 // Hinweis: Die Remove Methode prueft auf


42 [Link](new Point(2,1)); 42 // Wertegleichheit.
43 [Link](new Point(4,9)); 43 public class ListUnitTest{
44 [Link](new Point(9,3)); 44 [Test]
45 [Link](new Point(2,6)); 45 public void TestRemove(){
46 46 List<Point> points = new List<>();
47 Point p = new Point(2,1); 47

48 48 [Link](new Point(3,4));
49 [Link]([Link](p)); 49 [Link](new Point(5,2));
50 } 50 [Link](new Point(7,2));
51 } 51 [Link](new Point(2,2));

30
© Paul Panhofer

1 // ---------------------------------------- 2.2.2 foreach Schleife


2 // Method: Remove
Zur Verarbeitung von Collections stellt C# eine eige-
3 // ----------------------------------------
ne Form der for Schleife zur Verfügung: die foreach
4 [Link](4, [Link]);
Schleife.
5

6 Point p = new Point(5,2); Erklärung: foreach Schleife


7 [Link]([Link](p)); ‚ Die foreach Schleife wird verwendet um eine Col-
8 [Link](3, [Link]); lection von Werten einfach verarbeiten zu können.
9 }
10 } ‚ Da es sich bei dieser Schleifenart um einen read-only
11
Zugriff handelt können die Werte nur ausgelesen,
12 // ---------------------------------------- aber nicht verändert werden.
13 // Syntax: RemoveAt ‚ Werden Elemente im Schleifenkörper der foreach
14 // ---------------------------------------- Schleife in die Liste eingefügt oder aus der Liste ent-
15 // Unter Verwendung der RemoveAt Methode fernt, bricht die Schleife mit einem Fehler ab.
16 // wird ein Element an einem bestimmten
17 // Index geloescht. ‚ Die foreach Schleife beschreibt dabei den folgen-
18 public void RemoveAt(int index){...} den technischen Sachverhalt: Für jedes Element der
19
Liste wird sequentiell der Code des Schleifenkörpers
20 public class ListUnitTest{ ausgeführt.
21 [Test]
Codebeispiel: for vs. foreach
22 public void TestRemoveAt(){
1 // ----------------------------------------
23 List<Point> points = new List<>();
2 // Example: foreach vs. for
24
3 // ----------------------------------------
25 [Link](new Point(3,4));
4 public class ListUnitTest{
26 [Link](new Point(5,3));
5 [Test]
27 [Link](new Point(8,3));
6 public void TestForeach(){
28 [Link](new Point(7,7));
7 List<int> points = new List<>();
29 [Link](new Point(4,4));
8
30 [Link](new Point(2,4));
9 [Link](8);
31 [Link](new Point(4,1));
10 [Link](4);
32 [Link](new Point(5,7));
11
33 [Link](new Point(7,2));
12 int sum = 0;
34 [Link](new Point(4,9));
13
35 [Link](new Point(8,2));
14 foreach(int value in points){
36 [Link](new Point(9,6));
15 sum += value;
37 [Link](new Point(0,4));
16 }
38 [Link](new Point(4,4));
17
39 [Link](new Point(3,1));
18 [Link](12, sum);
40 [Link](new Point(2,7));
19
41 [Link](new Point(2,1));
20 sum = 0;
42
21
43 [Link](17, [Link]);
22 for(int i = 0; i < [Link]; i++){
44
23 sum += points[i];
45 [Link](3);
24 }
46 [Link](1);
25
47
26 [Link](12, summ);
48 [Link](15, [Link]);
27
49 }
28 }
50 }
29 }


31
Softwareentwicklung

2.3. Datenstruktur: Stack 2.3.2 Fallbeispiel: Stack


Das Verhalten eines Stacks wird durch folgende Me-
L Datenstruktur Stack thoden beschrieben.

In der Datenverarbeitung bezeichnet ein Verhalten: Datenstruktur Stack


Stack eine häufig eingesetzte dynamische 1 // ----------------------------------------
Datenstruktur. 2 // Syntax: Push
3 // ----------------------------------------
Bei der Verwendung eines Stack werden die 4 // Mit der Push Methode wird ein Element zum
Elemente oben auf den Stack gelegt - LIFO 5 // Stack hinzugefuegt. Das Element wird dabei
Prinzip. Die Elemente werden dabei überein- 6 // oben auf den Stack gelegt.
ander gestapelt und können nur in umgekehr- 7 public void Push(T item){...};
ter Reihenfolge vom Stapel ausgelesen wer- 8

den. 9 public class StackUnitTest{


10 [Test]
Ein Stack kann mit Hilfe der Datenstruktur einer 11 public void TestPush(){
Liste implementiert werden. 12 Point p1 = new Point(3,4);
13 Point p2 = new Point(8,3);
14
2.3.1 Verhalten von Stacks 15 Stack<Point> pointStack = new
In vielen Programmiersprachen sind Stacks bereits Stack<Point>();
16
in der Standardsprachbibliothek implementiert. Der
Stack kann dabei mit folgenden Methoden bearbeitet 17 [Link](p1);
werden. 18 [Link](p2);
19
Auflistung: Methoden 20 [Link](2, [Link]);
‚ push: Mit der Push Methode wird ein Element zum 21 }
Stack hinzugefügt. Das Element wird dabei oben 22 }
auf den Stack gelegt. 23

24 // ----------------------------------------
‚ pop: Mit der Pop Methode wird das oberste Element
25 // Syntax: Pop
vom Stapel entfernt.
26 // ----------------------------------------
‚ peek: Die Peek Methode gibt eine Referenz auf das 27 // Mit der Pop Methode wird das oberste
oberste Element im Stapel zurück. 28 // Element vom Stapel entfernt.
29 public T Pop(){...};
30

31 public class StackUnitTest{


32 [Test]
33 public void TestPop(){
34 Stack<Point> pointStack = new
Stack<Point>();
35

36 [Link](new Point(4,7));
37 [Link](new Point(0,0));
38

39 Point p = [Link]();
40 [Link](new Point(0,0), p);
41 [Link](2, [Link]);
42 }
43 }

32
© Paul Panhofer

Seite
Befehl Beschreibung

Push Die Methode fügt ein Element zum Stack hinzu. Dazu wird das Element oben auf 32
den Stack gelegt.
Pop Die Methode entfernt das oberste Objekt vom Stapel. 32
Peek Die Methode gibt eine Referenz auf das oberste Element im Stapel zurück. 33
Clear Die Methode loescht alle Objektereferenzen aus dem Stack. 33
Contains Die Methode prueft ob ein bestimmtes Element in der Liste enthalten ist. 34
ToArray Kopiert die im Stack verwalteten Objektreferenzen in ein Array 34
CopyTo Kopiert die im Stack verwalteten Objektreferenzen in ein Array. Es werden alle Ele- 34
mente ab einem bestimmten Index kopiert.

Abbildung 9. Stackmethoden

1 // ---------------------------------------- 1 // ----------------------------------------
2 // Syntax: Peek 2 // Syntax: Clear
3 // ---------------------------------------- 3 // ----------------------------------------
4 // Die Peek Methode gibt eine Referenz auf 4 // Die Clear Methode loescht alle Objektre-
5 // das oberste Element im Stapel zurueck. 5 // ferenzen aus dem Stack.
6 public T Peek(){...}; 6 public void Clear(){...};
7 7

8 public class StackUnitTest{ 8 public class StackUnitTest{


9 9

10 [Test] 10 [Test]
11 public void TestPeek(){ 11 public void TestClear(){
12 Stack<Point> pointStack = new 12 Stack<Point> pointStack = new
Stack<Point>(); Stack<Point>();
13 13

14 [Link](new Point(3,4)); 14 [Link](new Point(3,4));


15 [Link](new Point(3,1)); 15 [Link](new Point(7,1));
16 [Link](new Point(5,2)); 16 [Link](new Point(7,2));
17 [Link](new Point(8,7)); 17 [Link](new Point(3,7));
18 [Link](new Point(5,7)); 18 [Link](new Point(6,2));
19 [Link](new Point(2,1)); 19 [Link](new Point(2,1));
20 [Link](new Point(2,1)); 20 [Link](new Point(3,1));
21 [Link](new Point(2,8)); 21 [Link](new Point(1,6));
22 [Link](new Point(2,2)); 22 [Link](new Point(4,6));
23 [Link](new Point(2,1)); 23

24 24 [Link](9, [Link]);
25 Point p = [Link](); 25

26 26 [Link]();
27 [Link](12, [Link]); 27
28 [Link](new Point(2,1), p); 28 [Link](0, [Link]);
29 } 29 }
30 30

31 } 31 }

33
Softwareentwicklung

1 // ---------------------------------------- 1 // ----------------------------------------
2 // Syntax: Contains 2 // Methode: ToArray
3 // ---------------------------------------- 3 // ----------------------------------------
4 // Mit der Contains Methode wird geprueft 4 public class StackUnitTest{
5 // ob ein bestimmtes Element auf dem Stack 5 [Test]
6 // enthalten ist. 6 public void TestToArray(){
7 public bool Contains(T item){...}; 7 Stack<Point> stack = new
8 Stack<Point>();
9 // Hinweis: Die Contains Methode prueft auf 8

10 // Wertegleichheit .Implementieren Sie die 9 [Link](new Point(3,4));


11 // Equals Methode der Elementkalsse. 10 [Link](new Point(2,1));
12 11

13 public class StackUnitTest{ 12 [Link](2, [Link]);


14 13 Point[] points = [Link]();
15 [Test] 14 [Link](2, [Link]);
16 public void TestContains(){ 15

17 Stack<Point> pointStack = new 16 [Link](


Stack<Point>(); 17 [Link](), points[2]
18 18 );
19 [Link](new Point(3,4)); 19 }
20 [Link](new Point(2,1)); 20 }
21 [Link](new Point(2,1)); 21

22 [Link](new Point(2,1)); 22 // ----------------------------------------


23 [Link](new Point(7,2)); 23 // Syntax: CopyTo
24 [Link](new Point(7,3)); 24 // ----------------------------------------
25 [Link](new Point(2,1)); 25 // Kopiert die im Stack verwalteten Objekt-
26 [Link](new Point(2,1)); 26 // referenzen in ein Array. Welche Objekt-
27 [Link](new Point(3,1)); 27 // referenzen kopiert werden bestimmt der
28 [Link](new Point(1,6)); 28 // uebergebene Index
29 29 public void CopyTo(T[], int index){...};
30 [Link](12, [Link]); 30
31 31 public class StackUnitTest{
32 Point p = new Point(7,2); 32 [Test]
33 [Link]([Link](p)); 33 public void TestCopyTo(){
34 } 34 Stack<Point> stack = new
35 Stack<Point>();
36 } 35

37 36 [Link](new Point(3,4));
38 // ---------------------------------------- 37 [Link](new Point(2,1));
39 // Syntax: ToArray 38

40 // ---------------------------------------- 39 Point[] points = new


41 // Die ToArray Methode kopiert die am Stack Point[[Link] + 2];
42 // verwalteten Objektreferenzen in ein Array 40 points[0] = new Point(3,9);
43 public T[] ToArray(){...}; 41 points[1] = new Point(2,2);
44 42

45 // Hinweis: Beachten Sie dass in Collections 43 [Link](points,2);


46 // keine Objekte sondern Objektreferenzen 44 [Link](4, [Link]);
47 // verwaltet werden. 45

46 }
47 }

34
© Paul Panhofer

Seite
Befehl Beschreibung

Enqueue Mit der Enqueue Methode wird ein neues Element in eine Queue eingefügt. 38
Dequeue Mit der Dequeue Methode wird das als erste eingefügte Element aus einer Queue 36
entfernt.
Peek Die Peek Methode gibt eine Referenz auf das zuerst eingefügte Element einer 37
Queue zurück.
Clear Mit der Clear Methode wird eine Queue geleert. 37
Contains Mit der Contains Methode wird geprüft ob ein bestimmtes Element in der Queue 37
enthalten ist. Elemente werden dabei auf Wertegleichheit geprüft.
ToArray Die ToArray Methode kopiert die in der Queue verwalteten Objektreferenzen in 37
ein Array

Abbildung 10. Queuemethoden

2.4. Datenstruktur: Queue ❑

L Datenstruktur Queue
Eine Queue ist eine dynamische Datenstruktur
mit der eine beliebige Zahl von Elementen ver-
waltet werden kann.

Die Elemente der Queue werden in der Rei-


henfolge ausgelesen, in der sie in die Queue
eingefügt worden sind - FIFO Prinzip.

Queue werden gerne mit der Hilfe von Listen imple-


mentiert.

2.4.1 Verhalten von Queues

Queues verwalten die in ihnen enthaltenen Elemente


nach dem FIFO 7 Prinzip. Dabei werden folgende Me-
thoden unterstützt:

Auflistung: Methoden
‚ Enqueue: Mit der Enqueue Methode wird ein Ele-
ment in eine Queue eingefügt.

‚ Dequeue: Die Dequeue Methode entfernt das zu-


erst eingefügte Element aus einer Queue.

‚ Peek: Die Peek Methode gibt eine Referenz auf das


älteste Element einer Queue zurück.

7
First In - First Out

35
Softwareentwicklung

2.4.2 Fallbeispiel: Queue 1 // ----------------------------------------


2 // Syntax: Dequeue
Das Verhalten einer Queue wird durch folgende Me-
3 // ----------------------------------------
thoden beschrieben.
4 // Mit der Dequeue Methode wird das als er-
5 // ste eingefuegte Element aus einer Queue
Verhalten: Datenstruktur Queue
6 // entfernt.
1 // ---------------------------------------- 7 public T Dequeue(){...};
2 // Syntax: Enqueue 8
3 // ---------------------------------------- 9 public class QueueUnitTest{
4 // Mit der Enqueue Methode wird eine neues 10 [Test]
5 // Element in eine Queue eingefuegt 11 public void TestDequeue(){
6 public void Enqueue(){...}; 12 Queue<Point> queue = new Queue<>();
7
13
8 public class QueueUnitTest{ 14 [Link](new Point(3,2));
9 [Test] 15 [Link](new Point(2,6));
10 public void TestEnqueue(){ 16 [Link](new Point(7,6));
11 Queue<Point> queue = new Queue<>(); 17
12
18 [Link](3, [Link]);
13 [Link](new Point(3,2)); 19
14 [Link](new Point(6,2)); 20 Point p = [Link]();
15 [Link](new Point(1,3)); 21
16 [Link](new Point(2,3)); 22 [Link](2, [Link]);
17 [Link](new Point(2,3)); 23 [Link](new Point(3,2), p);
18 [Link](new Point(4,3)); 24 }
19 [Link](new Point(4,4)); 25 }
20
26
21 [Link](7, [Link]); 27 // ----------------------------------------
22 } 28 // Syntax: Peek
23
29 // ----------------------------------------
24 } 30 // Die Peek Methode gibt eine Referenz auf
31 // das zuerst eingefuegte Element einer
32 // Queue zurueck
33 public T Peek(){...};
34

35 public class QueueUnitTest{


36 [Test]
37 public void TestPeek(){
38 Queue<Point> queue = new Queue<>();
39

40 [Link](new Point(3,2));
41 [Link](new Point(6,1));
42

43 [Link](2, [Link]);
44

45 Point p = [Link]();
46

47 [Link](2, [Link]);
48 [Link](new Point(3,2), p);
49 }
50 }

36
© Paul Panhofer

1 // ---------------------------------------- 2.5. Datenstruktur: Dictionary


2 // Syntax: Contains
3 // ----------------------------------------
4 // Die Contains Methode prueft ob ein be- L Datenstruktur Dictionary
5 // stimmtes Element in einer Queue enthalten
Ein Dictionary ist eine dynamische Datenstruk-
6 // ist. Die Elemente werden dabei auf Werte-
tur zur Verwaltung von Schlüssel Werte Paaren.
7 // gleichheit geprueft.
8 public bool Contains(T elem){...}; Ein Dictionary zeigt dabei dasselbe Verhalten
9 wie ein Arrays. Im Gegensatz zu einem Array
10 public class QueueUnitTest{ muss der Index eines Dictionaries kein geord-
11 [Test] neter numerischer Wert sein.
12 public void TestContains(){
13 Queue<Point> queue = new Queue<>();
14
2.5.1 Fallbeispiel: Array vs. Dictionary
15 [Link](new Point(3,2));
16 [Link](new Point(6,1)); Beim Instanzieren eines Dictionaries wird der Daten-
17 typ des Index und der zu verwaltenden Elemente defi-
18 [Link]([Link](new niert.
Point(2,5)));
Codebeispiel: Array vs. Dictionary
19 }
20 } 1 // ----------------------------------------
21
2 // Array vs. Dictionary
22 // ---------------------------------------- 3 // ----------------------------------------
23 // Syntax: ToArray 4 public class DictionaryUnitTest{
24 // ---------------------------------------- 5 [Test]
25 // Die ToArray Methode kopiert die in einer 6 public void CompareCollection(){
26 // Queue verwalteten Objektreferenzen in 7 string[] phoneList1 = new string[100];
8
27 // ein Array.
28 public T[] ToArray(){...}; 9 phoneList1[0] = "0664/8972372";
29
10 phoneList1[1] = "0650/3232664";
11
30 public class QueueUnitTest{
31
12 Dictionary<String, String> phoneList2
32 [Test] = new Dictionary<String,String>();
13
33 public void TestToArray(){
34 Queue<Point> queue = new Queue<>(); 14 phoneList2["Haidvogl"] = "0664/89723";
35
15 phoneList2["Ferfeggy"] = "0650/32323";
36 [Link](new Point(3,2)); 16 phoneList2["Adler"] = "0650/56754";
37 [Link](new Point(6,1)); 17 }
38 [Link](new Point(6,1)); 18 }
39

40 [Link](3, [Link]); ❑
41

42 Point[] points = [Link]();


43 [Link](3, [Link]);
44

45 [Link](
46 points[0], [Link]()
47 );
48 }
49 }

37
Softwareentwicklung

Abbildung 11. Datenstruktur Queue

2.5.2 Fallbeispiel: Dictionary 1 // ----------------------------------------


2 // Syntax: Clear
Das Verhalten eines Dictionaries wird durch folgende
3 // ----------------------------------------
Methoden beschrieben.
4 // Die Clear Methode loescht alle Eintraege
5 // aus einem Dictionary
Verhalten: Datenstruktur Dictionary
6 public void Clear(){...}
1 // ---------------------------------------- 7
2 // Syntax: [] Operator 8 public class DictionaryUnitTest{
3 // ---------------------------------------- 9 [Test]
4 // Der Lesende und Schreibende Zugriff auf 10 public void TestClear(){
5 // die Elemente eines Dictionaries erfolgt 11 Dictionary<string, int> grades = new
6 // ueber den [] Operator Dictionary<string, int>();
7
12
8 public class DictionaryUnitTest{ 13 grades["Softwareentwicklung"] = 2;
9 [Test] 14 grades["Informationssysteme"] = 3;
10 public void TestReadWrite(){ 15 grades["Medientechnik"] = 1;
11 Dictionary<string, string> phoneList 16
= new 17 [Link]( 3,
Dictionary<string,string>(); 18 phoneList["Informationssysteme"]
12
19 );
13 phoneList["Haidvogl"] = "0664/89723"; 20
14 phoneList["Ferfeggy"] = "0650/32323"; 21 [Link](3, [Link]);
15 phoneList["Adler"] = "0650/98234"; 22
16 phoneList["Schanndl"] = "0650/21323"; 23 [Link]();
17
24 [Link](0, [Link]);
18 [Link](4, [Link]); 25 }
19
26 }
20 [Link]( 27
21 "0664/89723", 28 // ----------------------------------------
22 phoneList["Haidvogl"] 29 // Syntax: ContainsKey
23 ); 30 // ----------------------------------------
24
31 // Mit der ContainsKey Methode wird geprueft
25 [Link]( 32 // ob ein Dictionary einen bestimmten Wert
26 "0650/32323", 33 // als Index besitzt.
27 phoneList["Ferfeggy"] 34 public bool ContainsKey(T key){...}
28 ); 35
29
36 public class DictionaryUnitTest{
30 } 37 [Test]
31 } 38 public void TestContainsKey(){
39 Dictionary<string, int> grades = new
Dictionary<string, int>();
40

38
© Paul Panhofer

41 grades["Softwareentwicklung"] = 2; 1 // ----------------------------------------
42 grades["Informationssysteme"] = 3; 2 // Syntax: ContainsValue
43 grades["Dezentrale Systeme"] = 2; 3 // ----------------------------------------
44 grades["Medientechnik"] = 1; 4 // Mit der ContainsValue Methode wird ge-
45 5 // prueft ob ein Dictionary einen bestimmten
46 [Link]( 6 // Wert speichert.
47 [Link]("Medientechnik") 7 public bool ContainsValue(V value){...}
48 ); 8

49 } 9 public class DictionaryUnitTest{


50 } 10 [Test]
11 public void TestContainsValue(){
12 Dictionary<string, int> grades = new
Dictionary<string, int>();
13

14 grades["Softwareentwicklung"] = 2;
15 grades["Informationssysteme"] = 3;
16 grades["Medientechnik"] = 1;
17

18 [Link](
19 [Link](3);
20 )
21 }
22 }
23

24 // ----------------------------------------
25 // Syntax: Remove
26 // ----------------------------------------
27 // Mit der Hilfe der Remove Methode kann ein
28 // Schluesseleintrag aus einem Dictionary
29 // entfernt werden.
30 public bool Remove(T key){...}
31

32 public class DictionaryUnitTest{


33 [Test]
34 public void TestContainsKey(){
35 Dictionary<string, int> grades = new
Dictionary<string, int>();
36

37 grades["Softwareentwicklung"] = 2;
38 grades["Informationssysteme"] = 3;
39 grades["Medientechnik"] = 1;
40

41 [Link](3, [Link]);
42

43 [Link]("Medientechnik");
44

45 [Link](2, [Link]);
46 }
47 }

39
Softwareentwicklung

Seite
Befehl Beschreibung

Clear Die Clear Methode löscht alle Einträge aus einem Dictionary 39
ContainsKey Mit der ContainsKey Methode wird geprueft ob ein Dictionary einen bestimmten 39
Wert als Index besitzt.
ContainsValue Mit der ContainsValue Methode wird geprüft ob ein Dictionary einen bestimmten 39
Wert speichert.
Remove Mit der Hilfe der Remove Methode kann ein Schlüsseleintrag aus einem Dictionary 39
entfernt werden.

Abbildung 12. Dictionarymethoden

2.5.3 Wertezugriff 2.6. Indexer


Für den Zugriff auf die Werte eines Dictionary Objekts
stehen die Properties Values und Keys zur Verfügung. L Indexer

Codebeispiel: Wertezugriff Ein Indexer ist eine Property, die den direkten
Zugriff auf den Index einer Collection erlaubt.
1 // ----------------------------------------
2 // Dictionary Properties
3 // ----------------------------------------
4 public class DictionaryUnitTest{ 2.6.1 Indexer
5 [Test]
Ein Indexer wird wie jede andere Property einer Klasse
6 public void CompareCollection(){
definiert.
7 Dictionary<String, String> phoneList
8 = new Dictionary<String,String>(); Codebeispiel: Indexer
9
1 // ----------------------------------------
10 phoneList["Haidvogl"] = "0664/89723"; 2 // Definition: Indexer
11 phoneList["Ferfeggy"] = "0650/32323"; 3 // ----------------------------------------
12 phoneList["Adler"] = "0650/56754"; 4 public class GameEngine {
13
5
14 foreach(var person in [Link]){ 6 // Definition der Collection fuer den
15 [Link](person+", "); 7 // Indexer
16 } 8 private int[] playerIds = new int[16];
17
9
18 > Ausgabe 10 // Definition eines Indexers fuer das
19 Haidvogl, Ferfeggy, Adler 11 // playerIds Array
20
12 public int this[int i]{
21 foreach(var num in [Link]){ 13 get { return playerIds[i]; }
22 [Link](num + ", "); 14 set { playerIds[i] = value; }
23 } 15 }
24
16
25 > Ausgabe 17 public GameEngine(){
26 0664/89723 0650/32323 0650/56754 18 ...
27 } 19 }
28 } 20 }

40
© Paul Panhofer

1 // ---------------------------------------- .
2 // Beispiel: Indexer
3 // ----------------------------------------
4 public class GameEngineTest {
5

6 [Test]
7 public void TestIndexer(){
8 GameEngine ge = new GameEngine();
9

10 ge[0] = 34;
11 ge[1] = 54;
12 ge[2] = 98;
13

14 ge[3] = 14;
15 ge[4] = 32;
16 ge[5] = 76;
17

18 ge[6] = 34;
19 ge[7] = 11;
20 ge[8] = 23;
21

22 [Link](34, ge[0]);
23 [Link](54, ge[1]);
24 [Link](98, ge[2]);
25

26 [Link](14, ge[3]);
27 [Link](32, ge[4]);
28 [Link](76, ge[5]);
29

30 [Link](34, ge[6]);
31 [Link](11, ge[7]);
32 [Link](23, ge[8]);
33 }
34 }

41
Softwareentwicklung

. .

42
© Paul Panhofer

3. Datentyp: String 3.1. Instanzieren von Strings

L Datentyp String
String ist ein Datentyp zur Verarbeitung von
Zeichenketten.

3.1.1 String Klasse


Der String Datentyp wird in der System Collection des
.net Frameworks definiert.

Erklärung: String Klasse


‚ String ist ein Datentyp zur Speicherung bzw. Ver-
arbeitung von Zeichenketten. Die Klassenbezeichner
String und string können in Programmen dabei
synonym verwendet werden.

‚ Intern werden die Zeichen eines Strings in einem


char Array gespeichert.
01. Instanzieren von Strings 43 ❑

02. Stringobjekte 47
3.1.2 Instanzieren von Strings
03. Objektmethoden 51 Für das Instanzieren von Stringobjekten stellt die .Net
Spezifikation mehrere Möglichkeiten zur Verfügung.
04. Klassenmethoden 54
Auflistung: Instanzieren von Strings

L Stringliterale
Im Gegensatz zu anderen Klassen werden
Stringobjekte nicht durch den Aufruf eines
Konstruktors sondern durch die Angabe einer
Zeichenfolge in Anführungsstrichen definiert.

 Substring
Durch die Verwendung der Substring() Metho-
de, kann aus bestehenden Stringobjekten ein
neues Stringobjekt instanziert werden.

 Formatstrings
Formatstrings sind Stringliterale die nicht zur
Complilier- sonder Ausführungszeit eines Pro-
gramms ausgewertet werden.

43
Softwareentwicklung

3.1.3 Stringliterale 3.1.4 Substrings


Im Gegensatz zu anderen Klassen werden Stringob- Durch die Verwendung der Substring() Methode, kann
jekte nicht durch den Aufruf eines Konstruktors in- aus bestehenden Stringobjekten ein neues Stringobjekt
stanziert. instanziert werden.
Erklärung: Stringliterale Erklärung: Substrings
‚ Stringobjekte werden in der Regel durch die Anga- ‚ In der Stringklasse wird die Substring() Methode
be eines Stringliterals definiert. Ein Stringliteral ist definiert. Die Methode wird verwendet um einen Teil
eine Zeichenfolge in Anführungszeichen. einer Zeichenkette zu extrahieren und eine Kopie der
Zeichenfolge als Ergebnis zurückzugeben.
‚ Ein Stringliteral kann dabei aus beliebigen alphanu-
merischen Zeichen bzw. einer Reihe von Escapese- ‚ Die Stringklasse definiert dabei 2 Formen der
quenzen bestehen. Substring() Methode.

‚ Escapesequenzen sind Steuerzeichen zur Formatie- Syntax: Substrings


rung der Ausgabe in der Systemkonsole. 1 //------------------------------------------
2 // Syntax: Substring
Codebeispiel: Stringliterale 3 //------------------------------------------
1 //------------------------------------------ 4 -- Form 1
2 // Stringliterale 5 /*
3 //------------------------------------------ 6 * Die Methode extrahiert alle Werte des
4 // Erzeugen eines Stringobjekts. 7 * Strings ausgehend vom startIndex und
5 string greetings = "... Hallo World"; 8 * und gibt eine Kopie der Werte zurueck
6 [Link](greetings); 9 */
7 10 public string Substring(int startIndex);
8 > Ausgabe 11

9 ... Hallo World 12 -- Form 2


10 13 /*
11 // Escapesequenzen 14 * Die Methode extrahiert length Werte des
12 // Escapesequenzen werden verwendet um die 15 * Strings ausgehend vom startIndex und
13 // Ausgabe eines Strings in der Konsole 16 * und gibt eine Kopie der Werte zurueck
14 // zu formatieren. 17 */
15 string intro = "In einem Loch im Boden, da 18 public string Substring(
16 lebte ein \"Hobbit\".\n Nicht in einem 19 int startIndex, int length
17 feuchten, schmutigen ..."; 20 );
18 [Link](intrl); 21

19 22 //------------------------------------------
20 > Ausgabe 23 // Beispiel: Substring
21 In einem Loch im Boden, da lebte ein "Hobbit". 24 //------------------------------------------
22 Nicht in einem feuchten, schmutzigen ... 25 //Index: 012345678910
23 26 string name = "Gallenblase";
24 27

25 // Escapesequenzen Tabelle 28 string value1 = [Link](5);


26 \’ ... Single quote 29 string value2 = [Link](1,3);
27 \" ... Double quote 30

28 \\ ... Backslash 31 [Link](value1);


29 \b ... Backspace 32 [Link](value2);
30 \n ... New line 33

31 \t ... Horizontal tab 34 > Ausgabe


32 \v ... Vertical tab 35 blase
36 all


44
© Paul Panhofer

3.1.5 Formatstring 3.1.6 StringBuilder


Formatstrings sind eine besondere Form von Stringli- StringBuilder werden zum Erzeugen komplexer Zei-
teralen. chenketten verwendet.

Erklärung: Format String Die .Net Spezifikation definiert die StringBuilder


‚ Bei Formatstrings handelt es sich wie bei Stringli- Klasse zum Erzeugen und Verarbeiten komplexer
teralen um einfache Zeichenketten. Jedoch können Zeichenketten.
aus einem Formatstring heraus die Werte von ande-
Codebeispiel: StringBuilder
ren Variablen referenziert werden.
1 //------------------------------------------
‚ Ein Formatstring wird dabei immer mit dem $ Ope- 2 // Beispiel: StringBuilder
rator eingeleitet. 3 //------------------------------------------
4 // Instanzieren eines StringBuilder Objekts
Codebeispiel: Formatstring
5 StringBuilder builder = new StringBuilder();
1 //------------------------------------------ 6
2 // Formatstring 7 // Erzeugen eines Strings
3 //------------------------------------------ 8 string value = [Link]();
4 // Person Klasse 9 [Link](value);
5 public class Person { 10
6
11 > Ausgabe:
7 private readonly String _firstName; 12
8 private readonly String _lastName; 13
9
14 // Instanzieren eines StringBuilder Objekts
10 public FirstName { get => _firstName; } 15 // Initialisierung des Objekts mit der
11 public LastName { get => _lastName; } 16 // Zeichenkette Hallo
12
17 StringBuilder initialisedBuilder =
13 public Person(String firstName, String 18 new StringBuilder("Hallo Welt");
lastName){ 19
14 this._firstName = firstName; 20 // Erzeugen eines Strings
15 this._lastName = lastName; 21 string value = [Link]();
16 } 22 [Link](value);
17 } 23
18
24 > Ausgabe:
19 public class Programm{ 25 Hallo Welt
20 public static void Main(String[] args){ 26
21 Person p = new Person( 27
22 "Tobias", "Haidvogl" 28 //------------------------------------------
23 ); 29 // Syntax: Append
24
30 //------------------------------------------
25 // Instanzieren eines Formatstrings 31 /*
26 string greeting = 32 * Die Append Methode wird verwendet um
27 $"firstName: {[Link]} \n 33 * an die im StringBuilder gespeicherte
28 lastName: {[Link]} "; 34 * Zeichenfolge eine neue Zeichenkette
29
35 * anzuhaengen.
30 [Link](greeting); 36 *
31 } 37 * Fuer die Append Methoden sind mehrere
32 } 38 * Formen definiert.
33
39 */
34 > Ausgabe 40 public StringBuilder Append(var value)
35 firstName: Tobias
36 LastName: Haidvogl

45
Softwareentwicklung

1 //------------------------------------------ 1 //------------------------------------------
2 // Beispiel: Append 2 // Beispiel: Replace
3 //------------------------------------------ 3 //------------------------------------------
4 // Example 1 4 [Link]();
5 [Link]("BMI Datenformular - Person"); 5 [Link]("c:\\Programme\\java");
6 [Link]("firstName: "); 6 [Link](’\’, ’/’);
7 [Link]("Tobias"); 7 ’
8 [Link](); 8 String data = [Link]();
9 [Link]("lastName: "); 9 [Link](data);
10 [Link]("Haidvogl"); 10

11 [Link](); 11 > Ausgabe


12 [Link]("age: "); 12 c:/Programme/java
13 [Link](21); 13

14 [Link](); 14 //------------------------------------------
15 [Link]("married: "); 15 // Syntax: Insert
16 [Link](false); 16 //------------------------------------------
17 17 /*
18 String data = [Link](); 18 * Mit der Insert Methode wird an einem be-
19 [Link](data); 19 * stimmten Index im StringBuilder eine
20 20 * Zeichenkette eingefuegt.
21 > Ausgabe 21 */
22 22 public StringBuilder Insert(int i, var v);
23 BMI Datenformular - Person 23

24 firstName: Tobias 24 //------------------------------------------


25 lastName: Haidvogl 25 // Beispiel: Insert
26 age: 21 26 //------------------------------------------
27 married: false 27 [Link](11, "Franz");
28 28

29 // Example 2 29 data = [Link]();


30 [Link](", aus "); 30 [Link](data);
31 [Link]("Hamburg!"); 31

32 32 > Ausgabe
33 data = [Link](); 33

34 [Link](data); 34 firstName: Tobias Franz


35 35 lastName: Haidvogl
36 > Ausgabe 36 age: 21
37 37 married: false
38 Hallo Welt, aus Hamburg! 38

39 39 //------------------------------------------
40 //------------------------------------------ 40 // Syntax: Remove
41 // Syntax: Replace 41 //------------------------------------------
42 //------------------------------------------ 42 /*
43 /* 43 * Mit der Remove Methode wird ab einem
44 * Mit der Replace Methode kann ein bestimmtes 44 * bestimmten Index eine Zahl von Zeichen aus
45 * Zeichen im StringBuilder durch ein anderes 45 * der Zeichenfolge geloescht.
46 * Zeichen ersetzt werden. 46 */
47 */ 47 public StringBuilder Remove(
48 public StringBuilder Replace( 48 int index,
49 char oldValue, 49 int length
50 char newValue 50 );
51 );

46
© Paul Panhofer

3.2. Stringobjekte 3.2.2 Leere Strings


Ein leerer String kann in einem Programm auf 2 Wei-
String ist ein Datentyp zur Verarbeitung von Zeichen-
sen dargestellt werden: leere Zeichenfolge bzw. Null-
ketten.
referenz.

Erklärung: Leere Strings


3.2.1 Stringobjekte
‚ Eine leere Zeichenfolge bzw. der Verweis auf die
Verglichen mit anderen Klassen zeigen Stringobjekte Nullreferenz werden oft als dasselbe wahrgenommen,
in vielerlei Hinsicht jedoch ein ungewohntes Verhalten. stellen jedoch unterschiedliche Konzepte dar.

Erklärung: Stringobjekte
‚ Folgende Beispiel zeigen den konzeptionellen Unter-
schied auf.
‚ Zum Instanzieren von Stringobjekten wird kein
Konstruktor verwendet. Codebeispiel: Leere Strings
‚ Stringobjekte sind immutable8 . Die im Stringobjekt 1 //------------------------------------------
gespeicherte Zeichenkette kann nach der Instanzie- 2 // Leere Strings vs. Nullreferenz
rung nicht mehr geändert werden. 3 //------------------------------------------
4 public class StringTest {
Codebeispiel: Stringobjekte 5

1 //------------------------------------------ 6 [Test]
2 // Immutable 7 pulic void TestEmptyString(){
3 //------------------------------------------ 8 string str = "...hello";
4 // Stringobjekte sind immutable. Die Methoden 9

5 // der Stringklasse aendern nie die gegen- 10 string emptyStr = [Link];


6 // waertige Zeichenkette. Es wird eine neue 11 string nullStr = null;
7 // adaptierte Zeichenkette zurueckgegeben. 12 AssertAreNotEqual(emptyStr, nullStr);
8 13

9 string s1 = "A string is more "; 14 string tempStr = str + nullStr;


10 string s2 = "than the sum of its chars."; 15

11 16 // Die Nullreferenz geht verloren


12 // Es wird eine neue Zeichenkette generiert 17 AsserAreEqual("...hello", tempStr);
13 // die s1 zugeordnet wird. 18

14 s1 += s2; 19 string newStr = emptyStr + nullStr;


15 20 AssertAreNotSame(emptyStr, newStr);
16 s1 = "Hello" ; 21

17 s2 = s1; 22 // Leere Strings vs. Nullreferenz


18 AssertAreSame(s1, s2); 23 AssertAreEqual(0, [Link]);
19 24 AssertAreEqual(0, [Link]);
20 s1 += "World"; 25

21 AssertAreNotSame(s1, s2); 26 // NullReferenceException


22 27 [Link]([Link]);
23 [Link](s1); 28 }
24 [Link](s2); 29 }
25

26 > Ausgabe ❑
27 Hello World
28 Hello

8
Der Zustand eines Objekts kann nach der Instanzie-
rung nicht mehr geändert werden.

47
Softwareentwicklung

Abbildung 13. ASCII Code

. .

48
© Paul Panhofer

3.2.3 ASCII Code 3.2.4 Fallbeispiel: Codierung


String ist ein Datentyp zum Verarbeiten von Zeichen- Werden Zeichenketten im Netzwerk verschickt sollten
ketten. sie aus Sicherheitsgründen codiert werden.

Stringobjekte speichern Zeichenketten. Die Zeichen- Codebeispiel: ASCII Code


ketten werden dabei in Form von char Arrays ge-
1 //------------------------------------------
speichert.
2 // ASCII Code
Erklärung: Speichern von Zeichen 3 //------------------------------------------
‚ Um Zeichenketten verarbeiten zu können wird jedes 4 // Eine Zeichenkette soll kodiert werden
der Zeichen eines Strings in einen Zahlenwert um- 5 // in dem jedes Zeichen des Strings, durch
gewandelt. 6 // jenes Zeichen ersetzt wird dass vom
7 // Intergerwert her um 5 groesser ist.
‚ Umgekehrt kann einem Zahlenwert auck ein alpha- 8
numerisches Zeichen zugeordnet werden. 9 public class StringTest {
10

Codebeispiel: ASCII Code 11 [Test]


1 //------------------------------------------ 12 pulic void TestAsciiCode(){
2 // ASCII Code 13 String stringValue = "hello";
3 //------------------------------------------ 14

4 public class StringTest { 15 int[] intValue = new


5 int[[Link]];
6 [Test] 16 int index = 0;
7 pulic void TestAsciiCode(){ 17

8 String stringValue = "hello"; 18 foreach(char c in stringValue){


9 19 intValue[index++] = (int)c;
10 int[] intValue = new 20 }
int[[Link]]; 21

11 int index = 0; 22 [Link](104, intValue[0]);


12 23 [Link](101, intValue[1]);
13 foreach(char c in stringValue){ 24 [Link](108, intValue[2]);
14 intValue[index++] = (int)c; 25 [Link](108, intValue[3]);
15 } 26

16 27 StringBuilder str = new


17 [Link](104, intValue[0]); StringBuilder();
18 [Link](101, intValue[1]); 28

19 [Link](108, intValue[2]); 29 for(int i = 0; i < [Link];


20 [Link](108, intValue[3]); i++){
21 30 [Link]((char)(intValue[i] +
22 StringBuilder str = new 5));
StringBuilder(); 31 }
23 32

24 for(int i = 0; i < [Link]; 33 [Link](’m’, str[0]);


i++){ 34 [Link](’j’, str[1]);
25 [Link]((char)intValue[i]); 35 [Link](’q’, str[2]);
26 } 36 [Link](’q’, str[3]);
27 37

28 [Link]("hello", 38 [Link]("mjqqu",
[Link]()); [Link]());
29 } 39 }
30 } 40 }

❑ ❑

49
Softwareentwicklung

Seite
Befehl Beschreibung

Contains() Mit der Contains() Methode kann geprüft werden ob eine String eine bestimmte 51
Zeichenkette enthält.
EndsWith() Mit der EndsWith() Methode kann geprüft werden ob am Ende eines Strings eine 51
bestimmte Zeichenkette auftritt.
IndexOf() Mit der IndexOf() Methode kann geprüft werden an welcher Stelle eine bestimmte 51
Zeichenkette in einem String auftritt.
Insert() Mit der Methode Insert() kann an einem bestimmten Index in einen String eine 52
Zeichenkette eingefügt werden.
LastIndexOf() Mit der LastIndexOf() Methode kann der Index des letzten Auftretens einer Zei- 52
chenkette in einem String ermittelt werden.
Remove() Mit der Remove() Methode werden alle Zeichen ab einem bestimmten Index aus 53
einem String entfernt.
Replace() Mit der Replace Methode können alle Vorkommen einer bestimmten Zeichenket- 53
te durch eine andere Zeichenkette ersetzt werden.
Split() Mit der Split() Methode kann ein String in mehrere Zeichenketten aufgespalten 52
werden.
StartsWith Mit der StratsWith() Methode kann geprüft werden ob ein String mit einer bestimm- 51
ten Zeichenkette beginnt.
ToLower() Mit der ToLower() Methode wird ein String in Kleinschreibung umgewandelt. 53
ToUpper() Mit der ToUpper() Methode wird ein String in Großschreibung umgewandelt. 53
Trim() Mit der Trim() Methode können bestimmte Zeichen vom Anfang und Ende eines 54
Strings gelöscht werden.
TrimEnd() Mit der TrimEnd() Methode werden bestimmte Zeichen am Ende eines Strings 54
entfernt.
TrimStart() Mit der TrimStart() Methode werden bestimmte führende Zeichen aus einem String 54
entfernt.

Concat() Mit der Concat() Methode können mehrere Zeichenketten zu einem einzelnen 54
String verknüpft werden.
Join() Mit der Join() Methode können mehrere Zeichenketten zu einem einzelnen String 55
verknüpft werden. Zusätzlich wird nach jeder Zeichenkette ein Trennzeichen
eingefügt.
IsNullOrEmpty() Die IsNullOrEmpty Methode prüft ob ein String eine Nullreferenz oder ob er leer ist. ??

Length Die Length Property gibt die Anzahl der Zeichen eines String an. ??

Abbildung 14. Methoden und Properties der String Klasse

. .

50
© Paul Panhofer

3.3. Objektmethoden 3.3.2 Methode: Contains()


Mit der Contains() Methode kann geprüft werden ob
Der String Datentyp wird in der System Collection des
eine bestimmte Zeichenkette in einem String enthalten
.net Frameworks definiert.
ist.
Für die Bearbeitung von Zeichenketten definiert die Syntax: Contains() Methode
Stringklasse eine Reihe von Methoden.
1 //------------------------------------------
2 // Syntax: Contains()
3.3.1 Methode: IndexOf() 3 //------------------------------------------
4 public bool Contains (string value);
Mit der IndexOf Methode kann geprüft werden, an wel- 5

cher Stelle eine bestimmte Zeichenkette in einem String 6 //------------------------------------------


auftritt. 7 // Codebeispiele: Contains()
8 //------------------------------------------
Syntax: IndexOf() Methode
9 public class StringTest{
1 //------------------------------------------
10 [Test]
2 // Syntax: IndexOf()
11 public void TestContains(){
3 //------------------------------------------
12 string s1 = "In einem Loch im ...";
4 public int IndexOf(string value);
13 string s2 = "Loch";
5
14 [Link]([Link](s2));
6 // Mit dem startIndex Parameter kann angege-
15 }
7 // ben werden ab welchem Index die Pruefung
16 }
8 // erfolgt.
9

10 // Mit dem count Parameter wird bestimmt
11 // welches Vorkommen der Zeichenkette
12 // gemeint ist. 3.3.3 Methode: Starts/EndsWith()
13 public int IndexOf(
Mit der Starts/EndsWith() Methode kann geprüft
14 string value, int startIndex, int count
werden ob ein String mit einer bestimmten Zeichen-
15 );
kette beginnt bzw. endet.
16

17 //------------------------------------------ Syntax: EndsWith() Methode


18 // Codebeispiele: IndexOf() 1 //------------------------------------------
19 //------------------------------------------ 2 // Syntax: Starts/EndsWith()
20 public class StringTest{ 3 //------------------------------------------
21 4 public bool StartsWith(string value);
22 [Test] 5
23 public void TestIndexOf(){ 6 public bool EndsWith(string value);
24 string s1 = "c:/htlkrems/abgabe"; 7
25 8 //------------------------------------------
26 [Link](2, [Link]("/")); 9 // Codebeispiele: Start/EndsWith()
27 [Link]( 10 //------------------------------------------
28 11, 11 public class StringTest{
29 [Link]("/", 0, 2) 12 [Test]
30 ); 13 public void TestEndsWith(){
31 14 String[] vals = { "Hello!", "No."};
32 // Ist das Zeichen nicht im String 15
33 // enthalten wird -1 zurueckgegeben. 16 [Link](vals[0].EndsWith("."));
34 [Link](-1, [Link]("!")); 17 [Link](vals[1].EndsWith("."));
35 } 18 }
36 } 19 }

❑ ❑

51
Softwareentwicklung

3.3.4 Methode: LastIndexOf() 3.3.6 Methode: Split()


Mit der LastIndexOf() Methode wird der Index des Mit der Split() Methode kann ein String auf einzelne
letzten Auftretens einer Zeichenkette in einem String Zeichenketten aufgespalten werden.
bestimmt.
Syntax: Split() Methode
Syntax: LastIndexOf() Methode
1 //------------------------------------------
1 //------------------------------------------
2 // Syntax: Split()
2 // Syntax: LastIndexOf()
3 //------------------------------------------
3 //------------------------------------------
4 // Im char[] Array werden alle gewuenschten
4 public int LastIndexOf(string value);
5 // Trennzeichen definiert. Die Splitoptionen
5
6 // definieren das Verhalten der Split
6 //------------------------------------------
7 // Methode naeher.
7 // Codebeispiele: LastIndexOf()
8 public string Split(
8 //------------------------------------------
9 char[] delim,
9 public class StringTest{
10 StringSplitOptions option
10 public void TestLastIndexOf(){
11 );
11 string s1 = "c:/htlkrems/abgabe";
12
12
13 //------------------------------------------
13 [Link](11,
14 // Codebeispiele: Split()
[Link]("/"));
15 //------------------------------------------
14 [Link](-1,
16 public class StringTest{
[Link]("!"));
17 [Test]
15 }
18 public void TestSplit(){
16 }
19 string s1 = "c:/htlkrems/abgabe";
20
❑ 21 string[] split = [Link](
22 new char[]{’:’,’/’},
3.3.5 Methode: Insert()
23 [Link]
Mit der Insert() Methode kann ab einem bestimmten 24 );
Index eine Zeichenkette in den String eingefügt werden. 25

26 [Link]("c", split[0]);
Syntax: Insert() Methode 27 [Link]("htlkrems", split[1]);
1 //------------------------------------------ 28 [Link]("abgabe", split[2]);
2 // Syntax: Insert() 29

3 //------------------------------------------ 30 string s2 = "In einem Loch im Boden";


4 public string Insert(string value); 31

5 32 string wordSplit = [Link](


6 //------------------------------------------ 33 new char[]{’ ’},
7 // Codebeispiele: Insert() 34 [Link]
8 //------------------------------------------ 35 );
9 public class StringTest{ 36

10 public void TestInsert(){ 37 [Link](


11 string s1 = "J. Tolkien"; 38 3, [Link]
12 39 );
13 [Link]( 40 [Link]("In", wordSplit[0]);
14 "J.J. Tolkien", 41 [Link](
15 [Link](2, "J.") 42 "einem", wordSplit[1]
16 ); 43 );
17 } 44 }
18 } 45 }

❑ ❑

52
© Paul Panhofer

3.3.7 Methode: Remove() 1 //------------------------------------------


2 // Codebeispiele: Replace()
Mit der Remove() Methode werden alle Zeichen ab ei-
3 //------------------------------------------
nem bestimmten Index aus einer Zeichenkette gelöscht.
4 public class StringTest{
5 [Test]
Syntax: Remove() Methode
6 public void TestReplace(){
1 //------------------------------------------
7 string s1 = "c:\\htlkrems\\abgabe";
2 // Syntax: Remove()
8 string s2 = [Link]("\", "/");
3 //------------------------------------------
9 "
4 public string Remove(int startIndex);
10
5
11 [Link](
6 // Mit dem count Operator kann die Anzahl
12 "c:/htlkrems/abgabe", s2
7 // der loeschenden Zeichen beschraenkt
13 );
8 // werden.
14 }
9 public string Remove(
15 }
10 int startIndex, int count
11 );
12 //------------------------------------------ ❑
13 // Codebeispiele: Remove()
14 //------------------------------------------ 3.3.9 Methode: ToLower()/ToUpper()
15 public class StringTest{
16 [Test] Mit der ToLower()/ToUpper Methode wird ein String
17 public void TestRemove(){ in Kleinschreibung bzw. Großschreibung umgewandelt.
18 String name = "Julian Leonhard Bayer";
19 Syntax: ToLower/Upper() Methode
20 String s1 = [Link]; 1 //------------------------------------------
21 String s2 = [Link]; 2 // Syntax: ToLower()/ToUpper()
22 3 //------------------------------------------
23 s1 = [Link](6); 4 public string ToLower();
24 [Link]("Julian", s1); 5

25 6 public string ToUper();


26 s2 = [Link](6, 9); 7

27 [Link]("Julian Bayer", s2); 8 //------------------------------------------


28 } 9 // Codebeispiele: ToLower()/ToUpper()
29 } 10 //------------------------------------------
11 public class StringTest{
❑ 12 [Test]
13 public void TestChangeFace(){
14 String name = "Julian Bayer";
3.3.8 Methode: Replace() 15

Mit der Replace() Methode können die Vorkommen 16 [Link](


einer bestimmten Zeichenfolge durch eine andere Zei- 17 "julian Bayer", [Link]()
chenfolge ersetzt werden. 18 );
19

Syntax: Replace() Methode 20 [Link](


1 //------------------------------------------ 21 "JULIAN BAYER", [Link]()
2 // Syntax: Replace() 22 );
3 //------------------------------------------ 23

4 public string Replace( 24 [Link]("Julian Bayer", name);


5 String oldValue, 25 }
6 String newValue 26 }
7 );

53
Softwareentwicklung

3.3.10 Methode: Trim() 3.4. Klassenmethoden


Mit der trim() Funktion können bestimmte Zeichen Das .Net Framework definiert für den String Datentyp
vom Anfang und Ende des Strings gelöscht werden. eine Reihe von Klassenmethoden.

Syntax: Trim() Methode


1 //------------------------------------------ 3.4.1 Methode: Concat()
2 // Syntax: Trim Mit der Concat() Methode können mehrere Zeichen-
3 //------------------------------------------ ketten zu einem einzelnen String verknüpft werden.
4 // Entfernt alle Leerzeichen vom Anfang bzw.
5 // Ende des Strings Syntax: Concat() Methode
6 public string Trim(); 1 //------------------------------------------
7
2 // Syntax: Concat()
8 // Entfernt die im Parameter definierten 3 //------------------------------------------
9 // Zeichen vom Anfang bzw. Ende des Strings. 4 public static string Concat(string[] values);
10 public string Trim(char[] trimChars) 5
11
6 public static string Concat(
12 // Entfernt die im Parameter definierten 7 string s1, string s2
13 // Zeichen vom Anfang des Strings. 8 );
14 public string TrimStart(char[] trimChars) 9
15
10 //------------------------------------------
16 // Entfernt die im Parameter definierten 11 // Codebeispiele: Concat()
17 // Zeichen vom Ende des Strings. 12 //------------------------------------------
18 public string TrimEnd(char[] trimChars) 13 public class StringTest{
19
14 [Test]
20 //------------------------------------------ 15 public void TestConcat(){
21 // Codebeispiele: Trim() 16 string[] values = {
22 //------------------------------------------ 17 "welcome ", "in ", "the ",
23 public class StringTest{ 18 "htl ", "krems!"
24 [Test] 19 };
25 public void TestTrim(){ 20
26 String s1 = " Hallo Welt "; 21 [Link](
27
22 "Welcome in the htl krems!",
28 [Link]( 23 [Link](values);
29 "Hallo Welt", [Link]() 24 );
30 ); 25
31
26 string s1 = "Hallo ", s2 = "Welt";
32 char[] charsToTrim = {’*’, ’ ’}; 27
33 String s2 = 28 [Link](
34 "*** Much Ado About Nothing ***"; 29 "Hallo Welt",
35
30 [Link](s1, s2);
36 [Link]( 31 );
37 "Much Ado About Nothing", 32 }
38 [Link](charsToTrim) 33 }
39 );
40

41 [Link](
42 "Hallo Welt ", [Link]([’ ’]);
43 );
44 }
45 }

54
© Paul Panhofer

3.4.2 Methode: Join() 1 //------------------------------------------


2 // Codebeispiele: IsNullOrEmpty()
Mit der Join() Methode können mehrere Zeichenket-
3 //------------------------------------------
ten zu einem einzelnen String verknüpft werden. Zu-
4 public class StringTest{
sätzlich wird nach jeder Zeichenkette ein Trennzeichen
5 [Test]
eingefügt.
6 public void TestIsNullOrEmtpy(){
Syntax: Join() Methode 7 String s1 = null;
1 //------------------------------------------ 8 String s2 = [Link];
9
2 // Syntax: Join()
3 //------------------------------------------ 10 [Link](
4 public static string Join( 11 [Link](s1) &&
5 string separator, 12 [Link](s2)
6 string[] values 13 );
14
7 );
8
15 String s3 = "Hallo Welt";
16
9 //------------------------------------------
10 // Codebeispiele: Join() 17 [Link](
11 //------------------------------------------ 18 [Link](s3)
12 public class StringTest{ 19 );
13 [Test] 20 }
14 public void TestJoin(){ 21 }
15 string[] values = {"2", "4", "2"};
16 ❑
17 [Link](
18 "2, 4, 2",
19 [Link](", ", values);
20 );
21

22 string[] values2 = {
23 "JOIN", "TABLE"
24 };
25 [Link](
26 "JOIN_TABLE",
27 [Link]("_", values2);
28 );
29 }
30 }

3.4.3 Methode: IsNullOrEmpty()


Die IsNullOrEmpty Methode prüft bo ein String eine
Nullreferenz oder ob er leer ist.

Syntax: IsNullOrEmpty() Methode


1 //------------------------------------------
2 // Syntax: IsNullOrEmpty()
3 //------------------------------------------
4 public static bool IsNullOrEmpty(string s);

55
Softwareentwicklung

. .

56
© Paul Panhofer

4. Exception 4.1. Fehlerbehandlung

L Fehlerbehandlung
Die Fehlerbehandlung umfasst den richtigen
Umgang mit Ausnahmen und Fehlern.

4.1.1 Fehler und Ausnahmen


Eine Exception ist ein Fehler, der ohne Behandlung
zum Absturz oder zu unerwünschten Zuständen in ei-
nem Programm führt.
Erklärung: Fehlerbehandlung
‚ Exceptions treten immer erst zur Laufzeit eines
Programms auf.
‚ Exceptions treten z.B.: bei Arithmetischen Opera-
tionen (Division durch 0), der Verletzung von Array-
grenzen oder dem Zugriff auf nicht erzeugte Objekte
auf.
01. Fehlerbehandlung 57
‚ Tritt ein solcher Fehler in einem Programm auf, wird
von der C# Programmengine eine entsprechende
Exception geworfen.

Codebeispiel: Fehler und Ausnahmen


1 // ----------------------------------------
2 //
3 // ----------------------------------------
4 int i = 10;
5 int j = 1;
6

7 int[] values = new int[5];


8 Point p;
9

10 // Die folgende Arithmetische Operation


11 // fuehrt zu einem Fehler. Das System wirft
12 // in diesem Fall eine DivideByZeroException
13 // und beendet die Ausfuehrung.
14 int k = i/(j-1);
15

16 // Die fogende Anweisung fuehrt zu einem


17 // Fehler. Die C++ Laufzeitengine wirft einen
18 // IndexOutOfRangeException und beendet die
19 // Programmausfuehrung.
20 values[3] = values[6] - 1;
21

22 // Eine NullReferenceException wird geworfen.


23 p.X = 10;

57
Softwareentwicklung

Exception Beschreibung

SystemException SystemException is the base class that all non-application errors inherit from.
IndexOutOfRangeException The IndexOutOfRangeException is thrown anytime an array or collection is acces-
sed using an index outside its bounds.
NullReferenceException If you attempt to use an object that is considered a null object, the NullReference-
Exception will be thrown.
InvalidOperationException The InvalidOperationException is thrown when the state of an object cannot sup-
port the particular method call being attempted for that object instance.
ArgumentException As the name implies, ArgumentException is thrown when a call is made to a me-
thod using an invalid argument.
ArgumentNullException ArgumentNullException is inherited from ArgumentException, but is thrown speci-
fically when a method is called that doesn’t allow an argument to be null.
ArgumentOutOfRangeException Another child of ArgumentException, the ArgumentOutOfRangeException error
is thrown when a method expects argument values within a specified range, yet
the provided argument falls outside those bounds.
UnauthorizedAccessException Der Aufrufer der Methode hat nicht das Rechte um auf das Filesystem zuzugreifen.
ArgumentException Ein Methodenparameter ist leer oder beinhaltet unzulaessige Zeichen.
ArgumentNullException Ein Methodenparemeter ist eine Nullreferenz.
PathTooLongException Ein Dateisystempfad ist zu lang.

Abbildung 15. Exceptiontypen

4.1.2 Fehlerbehandlung ❑

Tritt zur Laufzeit eines Programms ein Fehler auf,


führt das in der Regel zum Absturz des Systems.

Erklärung: Fehlerbehandlung
‚ Wird von einem Benutzer beispielsweise einen
falscher Wert eingegeben, sollte dass nicht gezwun-
gendermassen zum Absturtz des Systems führen.

‚ Durch die Implementierung einer Fehlerbehand-


lung ist es möglich in Programmen auf Fehler zu
reagieren.

Syntax: Fehlerbehandlung
1 // ----------------------------------------
2 // Syntax: Fehlerbehandlung
3 // ----------------------------------------
4 try{
5 // Der try Block umfasst jene Anweisungen
6 // die einen Fehler ausloesen koennten.
7 }catch(ExceptionType e1){
8 // Im catch Block kann auf bestimmte Fehler
9 // reagiert werden.
10 }

58
© Paul Panhofer

4.1.3 Programmfluss: Fehlerbehandlung Syntax: Fehlerbehandlung


1 // ----------------------------------------
Der Programmfluss eines Programms bestimmt wel-
2 // Fehlerbehandlung: Division by null
che Anweisungen in einem Programm ausgeführt wer-
3 // ----------------------------------------
den.
4 // Schreiben Sie eine Fehlerbehandlung fuer
5 // unzulaessige Rechenoperationenen.
Erklärung: Programmfluss Fehlerbehandlung
6
‚ Tritt eine Ausnahme in einem der try Blöcke auf, 7 // ----------------------------------------
springt der Programmfluss des Programms zum ers- 8 // Fehlerbehandlung: Division by null
ten dem Fehler zugeordneten Ausnahmebehandler. 9 // ----------------------------------------
‚ Für einen try Block kann dabei eine beliebige Zahl 10 public class Programm {
von catch Blöcken definiert werden. Wenn für eine 11

Ausnahme kein Ausnahmebehandler definiert wur- 12 static double SafeDivision(


de, beendet das Programm die Ausführung mit einer 13 double x, double y
Fehlermeldung. 14 ){
15 if (y == 0)
‚ Nach der Ausnahmebehandlung springt der Pro- 16 throw new DivideByZeroException();
grammfluss zur ersten dem try/catch Block nach- 17
gestellten Anweisung. 18 return x / y;
19 }
20

21 public static void Main(String[] args) {


22

23 double a = 98, b = 0;
24 double result = 0;
25

26 try {
27 result = SafeDivision(a, b);
28

29 [Link](
30 "{0} divided by {1} = {2}",
31 a,
32 b,
33 result
34 );
35 } catch (DivideByZeroException e){
36 [Link]("Attempted
divide by zero.");
37 }
38 }
39 }

59
Softwareentwicklung

. .

60
© Paul Panhofer

. 5. FileIO

01. Filesystem 62

02. Filesystem: Verzeichnis 62

03. Filesystem: Datei 67

61
Softwareentwicklung

5.1. Filesystem 5.2. Filesystem: Verzeichnis


Die Directory Klasse entspricht der Abstraktion eines
L Filesystem Verzeichnises eines Filesystems.
Ein Filesystem ist die Schnittstelle zwischen ei-
nem Betriebssystem und den Daten eines Da- 5.2.1 Klassenmethode: Exists()
tenträgers.
Die Exists Methode prüft ob ein bestimmtes Verzeich-
Es legt fest wie das Betriebssystem Dateien auf nis im Filesystem existiert.
einem Datenträger benennt, speichert, orga-
nisiert bzw. verwaltet. Syntax: Exists() Methode
1 // ----------------------------------------
Ein Filesystem verwaltet Dateien und Verzeichnis-
2 // Syntax: Existis
sen.
3 // ----------------------------------------
Erklärung: Filesystem 4 public static bool Exists (
‚ Filesysteme sorgen mit unterschiedlichen Mitteln für 5 string path
eine sinnvolle Speichrung der Daten auf einem Da- 6 );
tenträger. Das leichte Wiederfinden und das siche-
re Abspeichern sind dabei wesentliche Aufgaben des ❑
Systems.

‚ Die Daten eines Filesystems sind dabei in Form ei-


nes Verzeichnisbaums strukturiert. Als Verzeichnis-
baum wird die hierarchische Gestalt des Dateisys-
tems bezeichnet.
‚ Der Verzeichnisbaum beginnt dabei bei einem Wur-
zeldatensatz und verzweigt sich dann beliebig. In je-
der Ebene des Baumes können sowohl Dateien als
auch Verzeichnisse liegen, letztere bilden die nächs-
te Ebenen des Baumes.

‚ Die Verzeichnisstruktur ergibt sich dadurch, dass


Verzeichnisse wiederum andere Verzeichnisse enthal-
ten können, ausgehend von einem Wurzelverzeich-
nis.

‚ Die FileIO Bibliothek der C++ Sprachspezifikation


definiert eine Reihe von Klassen für den einfachen
Zugriff auf ein Filesystem.

‚ Zentral kommen hier die Directory und Fiele Klas-


sen zum Einsatz.

62
© Paul Panhofer

Seite
Befehl Beschreibung

CreateDirectory() Die CreateDirectory Methode wird verwendet um eine Verzeichnis im File- 63


system anzulegen.
Delete() Die Delete Methode wird verwendet um Verzeichnisse im Filesystem zu 69
löschen.
Exists() Die Exists Methode prüft ob ein bestimmtes Verzeichnis im Filesystem 67
existiert.

GetCurrentDirectory() Mit der GetCurrentDirectory Methode kann ermittelt werden welches Ver- 66
zeichnis der Filedescriptor der Anwendung referenziert.
GetDirectories() Mit der GetDirectories Methode können alle Unterverzeichnisse eines Ver- 65
zeichnisses ermittelt werden die bestimmten Kriterien entsprechen.
GetDirectoryRoot() Die GetDirectoryRoot Methode wird verwendet um das Wurzelverzeichnis 66
für ein bestimmtes Verzeichnis zu ermitteln.
GetFiles() Die GetFiles Methode wird verwendet um alle Dateien zu ermitteln die in 66
einem bestimmten Verzeichnis gespeichert sind.
GetFileSystemEntries() Die GetFileSystemEntries wird verwendet um alle Dateien und Unterver- 65
zeichnisse für ein bestimmtes Verzeichnis zu finden.
GetParent() Mit der GetParent Methode kann das Vaterverzeichnis für ein Verzeichnis 66
ermittelt werden.
Move() Die Move Methode wird verwendet um eine Datei bzw. ein Verzeichnis im 64
Filesystem an eine andere Position zu schieben.

Abbildung 16. Klassenmethoden der Directory Klasse

5.2.2 Klassenmethode: CreateDirectory() 1 // ----------------------------------------


2 // Codebeispiel: CreateDirectory
Die CreateDirectory Methode wird verwendet um eine
3 // ----------------------------------------
Verzeichnis im Filesystem anzulegen.
4 public static void Main(String[] args){
5 string path = @"c:\MyDir";
Syntax: CreateDirectory() Methode
6
1 // ---------------------------------------- 7 try {
2 // Syntax: CreateDirectory 8 if([Link](path)) {
3 // ---------------------------------------- 9 [Link]("Path exists.");
4 public static DirectoryInfo CreateDirectory( 10 return;
5 string path 11 }
6 ); 12 [Link](path);
7
13
8 // ---------------------------------------- 14 }catch(UnauthorizedAccessException e){
9 // Exceptions: CreateDirectory 15 [Link]("Unauthorized Access");
10 // ---------------------------------------- 16 }catch(PathTooLongException e) {
11 // Beim Aufruf der Methode koennen die 17 [Link]("path too long");
12 // folgenden Fehler auftreten: 18 }
19 }

63
Softwareentwicklung

❑ 1 // ----------------------------------------
2 // Syntax: Move
3 // ----------------------------------------
5.2.3 Klassenmethode: Delete() 4 public static void Move(
Die Delete Methode wird verwendet um Verzeichnisse 5 string sourceDirName,
im Filesystem zu löschen. 6 string destDirName
7 );
Syntax: Delete() Methode 8

1 // ---------------------------------------- 9 // ----------------------------------------
2 // Syntax: Delete 10 // Codebeispiel: Move
3 // ---------------------------------------- 11 // ----------------------------------------
4 public static void Delete( 12 static void Main(string[] args){
5 string path 13 string sourceDirectory = @"C:\source";
6 ); 14 string destinationDirectory =
7 @"C:\destination";
8 // ---------------------------------------- 15

9 // Codebeispiel: Delete 16 try {


10 // ---------------------------------------- 17 [Link](
11 public static void Main(String[] args){ 18 sourceDirectory,
12 string path = @"C:\NewDirectory"; 19 destinationDirectory
13 string subPath = 20 );
14 @"C:\NewDirectory\NewSubDirectory"; 21 }catch (Exception e) {
15 22 [Link]([Link]);
16 try { 23 }
17 [Link](subPath); 24 }
18 [Link](subPath);
19

20 bool directoryExists = Directory
21 .Exists(path);
22

23 bool subDirectoryExists = Directory


24 .Exists(subPath);
25

26 [Link](
27 "top-level directory exists: "
28 + directoryExists
29 );
30 }catch(UnauthorizedAccessException e){
31 [Link]("UnauthorizedAccess");
32 }catch(PathTooLongException e){
33 [Link]("path too long");
34 }
35 }

5.2.4 Klassenmethode: Move()


Die Move Methode wird verwendet um eine Datei bzw.
ein Verzeichnis im Filesystem an eine andere Position
zu schieben.

Syntax: Move() Methode

64
© Paul Panhofer

5.2.5 Klassenmethode: GetDirectories() 1 // ----------------------------------------


2 // Codebeispiel: GetDirectories
Mit der GetDirectories Methode können alle Unterver-
3 // ----------------------------------------
zeichnisse eines Verzeichnisses ermittelt werden die be-
4 public static void Main(String[] args){
stimmten Kriterien erfüllen.
5 try {
6 string[] dirs =
Syntax: GetDirectories() Methode
[Link](
1 // ---------------------------------------- 7 @"c:\", "p*", "
2 // Syntax: GetDirectories 8 [Link]
3 // ---------------------------------------- 9 );
4 /* 10 } catch (Exception e) {
5 * @Param searchPattern: Beim searchPattern 11 [Link]("process failed!");
6 * String handelt es sich um eine sogenannte 12 }
7 * Suchmaske. Mit einer Suchmaske kann 13 }
8 * auf einfache Weise ein Menge von Zeichen-
9 * ketten mit einer bestimmten Struktur be-

10 * schrieben werden.
11 *
12 * z.B: Suchmaske Zeichenketten 5.2.6 Klassenmethode: GetFileSystemEntries()
13 * p p
14 * p* Alle Zeichenketten die
15 * mit einem p beginnen Die GetFileSystemEntries wird verwendet um alle Da-
16 * HTL* Alle Zeichenketten die teien und Unterverzeichnisse für ein bestimmtes Ver-
17 * mit HTL beginnen. zeichnis zu finden.
18 * *k* Alle Zeichenketten die
19 * ein k enthalten. Syntax: GetFileSystemEntries() Methode
20 * ?? Eine Zeichenfolge mit 1 // ----------------------------------------
21 * geanu 2 Zeichen 2 // Syntax: GetFileSystemEntries
22 * a? Eine Zeichenfolge mit 2 3 // ----------------------------------------
23 * Zeichen die mit a beg. 4 public static string[] GetFileSystemEntries(
24 * 5 string path,
25 * 6 string searchPattern
26 * @Param searchOption: Der Parameter 7 )
27 * steuert welche Unterverzeichnisse in die 8

28 * Suche integriert werden. 9 // ----------------------------------------


29 * 10 // Codebeispiel: GetFileSystemEntries
30 * [Link] 11 // ----------------------------------------
31 * [Link] 12 static void Main(string[] args){
32 * 13 try {
33 */ 14 string[] directoryEntries =
34 public static string[] GetDirectories( 15 [Link](path);
35 string path, 16

36 string searchPattern, 17 foreach (string str in


37 SearchOption searchOption directoryEntries){
38 ) 18 [Link](str);
39 19 }
40 // ---------------------------------------- 20 } catch (ArgumentNullException) {
41 // Codebeispiel: GetDirectories 21 [Link](
42 // ---------------------------------------- 22 "Path is a null reference."
43 // 1.1) Finden Sie alle Unterverzeichnisse 23 );
44 // die mit einem p beginnen. 24 }

65
Softwareentwicklung

5.2.7 Klassenmethode: GetFiles() 5.2.9 Klassenmethode: GetDirectoryRoot()


Die GetFiles Methode wird verwendet um alle Datei- Die GetDirectoryRoot Methode wird verwendet um
en zu ermitteln die in einem bestimmten Verzeichnis das Wurzelverzeichnis für ein bestimmtes Verzeichnis
gespeichert sind. zu ermitteln.
Syntax: GetFiles() Methode Syntax: GetDirectoryRoot() Methode
1 // ---------------------------------------- 1 // ----------------------------------------
2 // Syntax: GetFiles 2 // Syntax: GetDirectoryRoot
3 // ---------------------------------------- 3 // ----------------------------------------
4 public static string[] GetFiles( 4 public static string GetDirectoryRoot(
5 string path, 5 string path
6 string searchPattern 6 )
7 ) 7

8 8 // ----------------------------------------
9 // ---------------------------------------- 9 // Codebeispiel: GetDirectoryRoot
10 // Codebeispiel: GetFiles 10 // ----------------------------------------
11 // ---------------------------------------- 11 public static void Main(String[] args){
12 public static void Main(string args[]){ 12 string dir = @"C:\test";
13 try{ 13

14 string[] dirs = Directory 14 [Link](


15 .GetFiles(@"c:\"", "*txt"); 15 "Root directory: {0}",
16 16 [Link](dir)
17 } catch (Exception e) { 17 );
18 [Link]( 18 }
19 "The process failed: {0}",
20 [Link]()

21 );
22 }
23 } 5.2.10 Klassenmethode: GetCurrentDirectory()

❑ Mit der GetCurrentDirectory Methode kann ermittelt


werden welches Verzeichnis der Filedescriptor der An-
5.2.8 Klassenmethode: GetParent() wendung referenziert.

Mit der GetParent Methode kann das Vaterverzeichnis Syntax: GetCurrentDirectory() Methode
für ein Verzeichnis ermittelt werden. 1 // ----------------------------------------
2 // Syntax: GetCurrentDirectory
Syntax: GetParent() Methode
3 // ----------------------------------------
1 // ---------------------------------------- 4 public static string GetCurrentDirectory();
2 // Syntax: GetParent 5
3 // ---------------------------------------- 6 // ----------------------------------------
4 public static DirectoryInfo GetParent( 7 // Codebeispiel: GetCurrentDirectory
5 string path 8 // ----------------------------------------
6 ); 9 public static void Main(String[] args){
7
10 string path =
8 // ---------------------------------------- [Link]();
9 // Codebeispiel: GetParent 11
10 // ---------------------------------------- 12 [Link](
11
13 "The current directory is {0}",
12 . 14 path
15 );
❑ 16 }

66
© Paul Panhofer

❑ 5.3. Filesystem: Datei


Die File Klasse entspricht der Abstraktion einer Datei
eines Filesystems.

5.3.1 Klassenmethode: Exists()


Mit der Exists Methode kann geprüft werden ob eine
Datei im Filesystem existiert.

Syntax: Exists() Methode


1 // ----------------------------------------
2 // Syntax: Exists
3 // ----------------------------------------
4 public static bool Exists(String path);

67
Softwareentwicklung

Seite
Befehl Beschreibung

AppendAllLines() Die AppendAllLines Methode wird verwendet um eine Liste von Strings 70
an das Ende einer Textdatei zu schreiben. Existiert die Datei nicht wird sie
angelegt.
AppendAllText() Die AppendAllText Methode wird verwendet um einen String an das Ende ??
einer Textdatei zu schreiben. Existiert die Datei nicht wird sie angelegt.
AppendText() Die Methode wird verwendet um Zeichenkette an eine Textdatei 69
anzuhängen.
CreateText() Die CreateText Methode wird verwendet um Textdateien im Filesystem 68
anzulegen.
Delete() Die Delete Methode wird verwendet um Dateien zu löschen. 69
Exists() Mit der Exists Methode kann geprüft werden ob eine Datei im Filesystem 67
existiert.
OpenRead() Mit der OpenRead Methode wird eine Datei geöffnet und deren Inhalt ??
gelesen.
OpenText() Die OpenText Methode wird verwendet um eine Textdatei zu öffnen. 70
OpenWrite() Mit der OpenWrite Methode wird eine Datei für den schreibenden Zugriff ??
geöffnet. Existiert die Datei nicht wird sie angelegt.
ReadAllText() Mit der ReadAllText Methode wird eine Datei geöffnet und der Inhalt ??
ausgelesen.
ReadLines() 69
WriteAllLines() Die WriteAllLines Methode wird verwendet um eine neue Datei anzulegen ??
und eine Liste von Zeichenketten in die Datei einzutragen.
WriteAllText() Die WriteAllText Methode wird verwendet um eine neue Datei mit einem 68
bestimmten Textinhalt im Filesystem anzulegen. Existiert die Datei bereits
wird sie überschrieben.

Abbildung 17. Klassenmethoden der File Klasse

5.3.2 Klassenmethode: WriteAllText() 5.3.3 Klassenmethode: CreateText()


Die WriteAllText Methode wird verwendet um eine Die CreateText Methode wird verwendet um Textda-
neue Datei mit einem bestimmten Textinhalt im Fi- teien im Filesystem anzulegen.
lesystem anzulegen. Existiert die Datei bereits wird sie
überschrieben. Syntax: CreateText() Methode
1 // ----------------------------------------
Syntax: WriteAllText() Methode
2 // Syntax: CreateText
1 // ----------------------------------------
3 // ----------------------------------------
2 // Syntax: WriteAllText
4 public static StreamWriter CreateText(
3 // ----------------------------------------
5 String path
4 public static void WriteAllText(
6 )
5 string path,
7
6 string contents
8 // ----------------------------------------
7 );
9 // Codebeispiel: CreateText
10 // ----------------------------------------
❑ 11 public static void Main(string[] args) {

68
© Paul Panhofer

12 string path = @"c:\temp\[Link]"; 5.3.5 Klassenmethode: ReadLines()


13

14 if (![Link](path)) {
Syntax: ReadLines() Methode
15 using (StreamWriter sw =
1 // ----------------------------------------
[Link](path)){
2 // Syntax: ReadLines
16 [Link]("Hello");
3 // ----------------------------------------
17 [Link]("And");
4 public static IEnumerable<string> ReadLines(
18 [Link]("Welcome");
5 string path
19 }
6 )
20 }
7 // ----------------------------------------
21
8 // Codebeispiel: ReadLines
22 using (StreamReader sr =
9 // ----------------------------------------
[Link](path)){
10 foreach (string line in
23 string s = "";
[Link](@"d:\data\[Link]")){
24 while ((s = [Link]()) != null){
11 [Link](line);
25 [Link](s);
12 }
26 }
27 }
28 } ❑

❑ 5.3.6 Klassenmethode: AppendText()


Die Methode wird verwendet um Zeichenkette an eine
Textdatei anzuhängen.
5.3.4 Klassenmethode: Delete()
Syntax: AppendText() Methode
Die Delete Methode wird verwendet um Dateien zu 1 // ----------------------------------------
löschen. 2 // Syntax: AppendText
3 // ----------------------------------------
Syntax: Delte() Methode
4 public static StreamWriter AppendText(
1 // ----------------------------------------
5 string path
2 // Syntax: Delete
6 )
3 // ----------------------------------------
7
4 public static void Delete(
8 // ----------------------------------------
5 string path
9 // Codebeispiel: AppendText
6 )
10 // ----------------------------------------
11 public static void Main(string[] args){
❑ 12 string path = @"c:\temp\[Link]";
13

14 if (![Link](path)){
15 using (StreamWriter sw =
16 [Link](path)){
17 [Link]("Hello and");
18 [Link]("Welcome");
19 }
20 }
21 using (StreamWriter sw =
22 [Link](path)){
23 [Link]("This is extra");
24 }
25 }

69
Softwareentwicklung

5.3.7 Klassenmethode: OpenText() 15 List<string> data = new List<string>();


16
Die OpenText Methode wird verwendet um eine Text- 17 [Link]("data 1");
datei zu öffnen. 18 [Link]("data 2");
Syntax: OpenText() Methode 19 [Link]("data 3");
20
1 // ----------------------------------------
2 // Syntax: OpenText 21 // Open the file to read from.
3 // ---------------------------------------- 22 [Link](path, data);
4 public static StreamReader OpenText( 23 }
5 string path
6 ) ❑

5.3.9 Klassenmethode: WriteAllLines()


1 // ----------------------------------------
2 // Codebeispiel: OpenText Die WriteAllLines Methode wird verwendet um eine
3 // ---------------------------------------- neue Datei anzulegen und eine Liste von Zeichenketten
4 public static void Main(string[] args){ in die Datei einzutragen.
5 string path = @"c:\temp\[Link]";
6
Syntax: WriteAllLines() Methode
7 using (StreamReader sr = 1 // ----------------------------------------
8 [Link](path)){ 2 // Syntax: WriteAllLines
9 string s = ""; 3 // ----------------------------------------
10 while ((s = [Link]()) != null){ 4 public static void WriteAllLines(
11 [Link](s); 5 string path,
12 } 6 IEnumeragle<string> contents
13 } 7 )
14 } 8

9 // ----------------------------------------
10 // Codebeispiel: WriteAllLines

11 // ----------------------------------------
12 public static void Main(string[] args){
5.3.8 Klassenmethode: AppendAllLines() 13 string path = @"c:\temp\[Link]";
14

Die AppendAllLines Methode wird verwendet um ei- 15 List<string> data = new List<string>();
ne Liste von Strings an das Ende einer Textdatei zu 16

schreiben. Existiert die Datei nicht wird sie angelegt. 17 [Link]("data 1");
18 [Link]("data 2");
Syntax: AppendAllLines() Methode 19 [Link]("data 3");
1 // ---------------------------------------- 20

2 // Syntax: AppendAllLines 21 // Open the file to read from.


3 // ---------------------------------------- 22 [Link](path, data);
4 public static void AppendAllLines( 23 }
5 string path,
6 IEnumerable<string> contents ❑
7 )
8

9 // ----------------------------------------
10 // Codebeispiel: AppendAllLines
11 // ----------------------------------------
12 public static void Main(string[] args){
13 string path = @"c:\temp\[Link]";
14

70
© Paul Panhofer

6. Appendix A: Muster 6.1. Entwurfsmuster

6.1.1 Grundlagen

L Entwurfsmuster
Ein Entwurfsmuster - Design Pattern - be-
schreibt ein bestimmtes Entwurfsproblem in
der Softwareentwicklung, sowie ein Schema
zu seiner Lösung.

Erklärung: Entwurfsmuster
‚ Entwurfsmuster helfen bei der Lösung immer wieder
auftretender Probleme in der Softwareentwicklung.
‚ Design Pattern sind dabei das Result der 30 jährigen
Erfahrung der Softwarecomunity. Man darf davon
ausgehen, dass sie für ein bestimmtes Problem die
bestmögliche Lösung darstellen.
‚ Design Patterns werden in der Objektorientierten
Programmierung als Standard angesehen. Softwa-
01. Entwurfsmuster 71 rearchitekten greifen auf sie zurück, um ihre Pro-
gramme zu entwerfen.
02. Erzeugungsmuster 72

03. Strukturmuster 75
6.1.2 Arten von Pattern
Je nach Entwicklungsfokus unterscheidet man unter-
schiedliche Formen von Entwurfsmustern.

Auflistung: Arten von Entwurfsmustern

r Idiom
Idiome sind Entwurfsmuster die Teil der eigent-
lichen Programmiersprache sind.

Annotationen sind z.B. ein Idiom das nur in


bestimmten Programmiersprachen unterstützt
werden.

 Entwurfsmuster
Entwurfsmuster beschreiben das Zusammen-
spiel von Klassen.

 Architekturmuster
Architekturmuster beschreiben das Zusam-
menspiel von Komponenten.

71
Softwareentwicklung

6.1.3 Einsatz von Entwurfsmustern 6.2. Erzeugermuster


Entwurfsmuster sind ein grundlegendes Konzept der
Erzeugermuster unterstützen das Erzeugen von
Objektorientierten Programmierung.
komplexen Objekten. Der Erzeugungsprozess für
Objekte kann gekapselt werden.
Analyse: Einsatz von Entwurfsmustern
‚ Muster repräsentieren wesentliche Konzepte der
Softwareentwicklung und bringen sie in eine ver- 6.2.1 Erzeugermuster - Singleton
ständliche Form. Muster helfen in diesem Sinne Ent-
würfe zu verstehen und sie zu dokumentieren.
L Singleton
‚ Muster verbessern die Kommunikation im Team.
Das Singleton Entwurfsmuster definiert eine
Entwurfsmuster bilden eine nützliche Terminologie
Klassenstruktur, die lediglich das Erzeugen ei-
für die Kommunikation unter Entwicklern.
ner einzelnen Instanz der Klasse erlaubt.
‚ Muster dokumentieren und fördern den Stand der
Der Zugriff auf die Instanz ist global möglich.
Technik. Der Einsatz von Entwurfsmuster hilft das
Suchen von Lösungen für Probleme, deren Lösungen
bekannt sind, zu vermeiden.
Erklärung: Motivation und Kontext
‚ Zusammenfassend kann man sagen dass Entwurfs- ‚ In einer Softwareanwendung soll es für den Daten-
muster die Codestruktur und damit die Codequali- banktreiber nur ein einzelne Instanz im System ge-
tät innerhalb von Softwarekomponenten verbessern. ben. Jeder Datenbankzugriff kann dann einfach über
den Treiber synchronisiert werden.

‚ Das Singelton Entwurfsmuster erlaubt dabei einen
kontrollierten Zugriff auf die Instanz der Klasse.
6.1.4 Kategorien von Entwurfsmustern
Je nach Einsatzgebiet werden unterschiedliche Katego- Codebeispiel: Fallbeispiel: Singleton
rien von Entwurfsmustern definiert. 1 //------------------------------------------
2 // Entwurfsmuster: Singleton
Auflistung: Kategorien von Entwurfsmustern 3 //------------------------------------------
‚ Erzeugermuster: Erzeugermuster unterstützen das 4 // Das Singelton Entwurfsmuster gibt eine
Erzeugen von komplexen Objekten. Der Erzeu- 5 // bestimmte Struktur fuer die Zielklasse
gungsprozess für Objekte wird gekapselt. 6 // des Musters vor.
7
‚ Verhaltensmuster: Verhaltensmuster beschreiben
8 // Das Muster umfasst eine einzelne Klasse
die Zuständigkeiten und Interaktionen zwischen Ob-
jekten.

72
© Paul Panhofer

1 //------------------------------------------ 6.2.2 Erzeugermuster - Factory


2 // Entwurfsmuster: Singleton
3 //------------------------------------------
L Factory
4 // Das Singleton Entwurfmuster definiert eine
5 // Klassenstruktur, die lediglich das Erzeu- Das Factory Entwurfsmuster dient der Entkop-
6 // gen einer Instanz der Klasse erlaubt. pelung des Clients von der konkreten Instan-
7 zierung eines Objekts.
8 public class Logger{
9 // In der Klasse selbst wird eine
Erklärung: Factory
10 // Instanz erzeugt und an ein Feld des
11 // Klassenobjekts gebunden. ‚ Für komplexe Objekte wird der Erstellungscode des
12 private static Logger instance = new Objekts in eine eigene Klasse ausgelagert.
Logger(); ‚ Dadurch kommt es zu einer Entkoppelung der Lo-
13
gik für die Objektverarbeitung und der Objekter-
14 public const bool LOG_TO_CONSOLE = true; zeugung.
15
Codebeispiel: Factory
16 // Damit keine Instanzen der Klasse
17 // erzeugt werden koennen wird der Kon- 1 // ----------------------------------------
18 // struktor private gesetzt. 2 // Erzeugungsmuster: Factory
19 private Logger(){ 3 // ----------------------------------------
20
4 public interface IQuackBehavior{
21 } 5 string Quack();
22
6 }
7
23 // Fuer den globalen Zugriff wird eine
24 // Klassenmethode geschrieben. 8 public class RedheadDuck : IQuackBehavior{
25 public static final Logger getInstance(){ 9 public string Quack(){
26 return instance; 10 return "... quack quack";
27 } 11 }
28
12 }
13
29 public void Log(String message){
30 if(LOG_TO_CONSOLE) 14 public class MarbledDuck : IQuackBehavior{
31 [Link](message); 15 public string Quack(){
32 } 16 return "... qua qua qua";
33
17 }
34 } 18 }
19
35

36 //------------------------------------------ 20 public class RubberDuck : IQuackBehavior{


37 // Fallbeispiel: Singleton 21 public string Quack(){
38 //------------------------------------------ 22 return "... squeeze";
39 public class Programm{ 23 }
40
24 }
25
41 public static void Main(string[] args){
42 Logger.LOG_TO_CONSOLE = true; 26 public class DuckDecoy : IQuackBehavior{
43
27 public string Quack(){
44 Logger logger =[Link](); 28 return "... QUACK QUACK";
45 [Link]("Hallo Welt"); 29 }
46 } 30 }
47 }

73
Softwareentwicklung

1 // ---------------------------------------- 1 // ----------------------------------------
2 // Erzeugungsmuster: Factory 2 // Erzeugungsmuster: Factory
3 // ---------------------------------------- 3 // ----------------------------------------
4 public class DuckSimulator { 4 public class DuckFactory : IDuckFactory{
5 public void Simulate(List<IQuackBehavior> 5 public IQuackBehavior CreateReadHDuck(){
ducks){ 6 return new ReadHeadDuck();
6 foreach(IQuackBehaviour duck in ducks){ 7 }
7 [Link]([Link]()); 8

8 } 9 public IQuackBehavior CreateMarbledDuck(){


9 } 10 return new MarbledDuck();
10 } 11 }
11 12

12 // Die Schnittstelle der Factory Klasse 13 public IQuackBehavior CreateRubberDuck(){


13 public interface IDuckFactory{ 14 return new RubberDuck();
14 IQuackBehavior CreateReadHeadDuck(); 15 }
15 IQuackBehavior CreateMarbledDuck(); 16

16 IQuackBehavior CreateRubberDuck(); 17 public IQuackBehavior CreateGoose(){


17 IQuackBehavior CreateDuckDecoy(); 18 return new HonkAdapter(new Goose());
18 } 19 }
19 20 }
20 public class DecoratedDuckFacotry : 21

IDuckFactory{ 22 public class Programm{


21 23 public static void Main(String[] args){
22 public IQuackBehavior CreateReadHDuck(){ 24 List<IQuackBehavior> ducks = new
23 return new OutputDecorator(new List<>();
QuackCountDecorator(new 25 IDuckFactory factory = new
ReadHeadDuck())); DecoratedDuckFactory();
24 } 26

25 27 [Link]([Link]());
26 public IQuackBehavior CreateMarbledDuck(){ 28 [Link]([Link]());
27 return new OutputDecorator(new 29 [Link]([Link]());
QuackCountDecorator(new 30 [Link]([Link]());
MarbledDuck())); 31 [Link]([Link]());
28 } 32

29 33 DuckSimulator sim = new


30 public IQuackBehavior CreateRubberDuck(){ DuckSimulator();
31 return new OutputDecorator(new 34 [Link](ducks);
QuackCountDecorator(new 35

RubberDuck())); 36 factory = new DuckFactory();


32 } 37

33 38 [Link]();
34 public IQuackBehavior CreateGoose(){ 39

35 return new OutputDecorator(new 40 [Link]([Link]());


QuackCountDecorator(new 41 [Link]([Link]());
HonkAdapter(new Goose())); 42

36 } 43 [Link](ducks);
37 } 44 }
45 }

74
© Paul Panhofer

6.3. Strukturmuster 1 //-----------------------------------------


2 // Entwurfsmuster: Adapter
Strukturmuster beschreiben die Struktur komple- 3 //-----------------------------------------
xer Objekte zur Laufzeit. 4 public interface IHonkBehavior{
5 public string Honk();

L |  6

7
}

8 public class HonkAdapter : IQuackBehavior{


6.3.1 Strukturmuster - Adapter 9

10 private IHonkBehaviour _honkable;


11
L Adapter 12 public HonkAdapter(IHonkBehavior
Mit einem Adapter kann die Schnittstelle eines honkable){
Objekt zur Laufzeit verändert werden. 13 this._honkable = honkable;
14 }
15

Erklärung: Motivation und Kontext 16 public string Quack(){


‚ In ein bestehendes Softwaresystem, sollen die Klas- 17 return this._honkable.Honk();
sen einer externen Klassenbilothek integriert wer- 18 }
den. Die Schnittstellendefinitionen beider Systeme 19

werden in der Regel nicht kompatibel sein. 20 }


21

22 public class Goose : IHonkBehaviour{


Erklärung: Eigenschaften eines Adapters
23 public string Honk(){
‚ Der Adapter fungiert als Vermittler, der Anfragen 24 return "... honk honk";
vom Client erhält und diese in Anfragen umwandelt, 25 }
die die neuen Klassen verstehen. 26 }
‚ Klassen mit inkompatiblen Schnittstellen können 27

damit in fremde Softwaresysteme integriert werden. 28 public class Programm{


29 public static void Main(String[] args){
30 List<IQuackBehavior> ducks = new
Codebeispiel: Entwurfsmuster: Adapter
List<>();
1 //-----------------------------------------
31
2 // Entwurfsmuster: Adapter
32 [Link](new ReadHeadDuck());
3 //-----------------------------------------
33 [Link](new MarbledDuck());
4 public interface IQuackBehavior{
34 [Link](new HonkAdapter(new
5 string Quack();
Goose()));
6 }
35
7
36 DuckSimulator sim = new
8 public class RedheadDuck : IQuackBehavior{
DuckSimulator();
9 public string Quack(){
37 [Link](ducks);
10 return "... quack quack";
38 }
11 }
39 }
12 }
40
13
41 > Ausgabe
14 public class MarbledDuck : IQuackBehavior{
42
15 public string Quack(){
43 "... quack quack"
16 return "... qua qua qua";
44 "... qua qua qua"
17 }
45 "... honk honk"
18 }

75
Softwareentwicklung

6.3.2 Strukturmuster - Dekorator 1 //-----------------------------------------


2 // Entwurfsmuster: Dekorator
3 //-----------------------------------------
L Dekorator
4 // Immer wenn die Quack() Methode aufgerufen
Mit einem Dekorator kann das Verhalten von 5 // wird soll ein interner Zaehler mitgezaehlt
Objekten zur Laufzeit verändert werden. 6 // werden.
7

8 // Zusaetzlich soll vor der Ausgabe jedesmal


Erklärung: Motivation und Kontext 9 // noch die Zeichenkette "Output:" auszugeben.
‚ Oft ist es notwendig das Verhalten von Objekten 10

zur Laufzeit ändern zu können. 11 public class OutputDecorator :IQuackBehavior{


12 private IQuackBehavior _quackable;
Erklärung: Eigenschaften von Dekoratoren 13

14 public OutputDecorator(IQuackBehavior q){


‚ Dekorierer haben besitzen denselben Datentyp, wie
15 this._quackable = q;
die Objekte, die sie dekorieren. Damit kann der De-
16 }
korierer stellvertretend für das zu dekorierende Ob-
17 public void Quack(){
jekt verwendet werden.
18 return "Output: " + _quackable.Quack();
‚ Der Dekorierer fügt zur Laufzeit sein Verhalten dem 19 }
zu dekorierenden Objekt hinzu. 20 }
21

Codebeispiel: Entwurfsmuster: Dekorator 22 public class QuackCountDecorator :


IQuackBehavior{
1 //-----------------------------------------
23 private IQuackBehavoir _quackable;
2 // Entwurfsmuster: Dekorator
24 public static int COUNTER = 0;
3 //-----------------------------------------
25
4 public interface IQuackBehavior{
26 public QuackCountDecorator(IQuackBehavior
5 string Quack();
quackable){
6 }
27 this._quackable = quackable;
7
28 }
8 public class RedheadDuck : IQuackBehavior{
29
9 public string Quack(){
30 public string Quack(){
10 return "... quack quack";
31 ++COUNTER;
11 }
32 return _quackable.Quack();
12 }
33 }
13
34 }
14 public class MarbledDuck : IQuackBehavior{
35
15 public string Quack(){
36 public class Programm{
16 return "... qua qua qua";
37 public static void Main(String[] args){
17 }
38 List<IQuackBehavior> ducks = new
18 }
List<>();
19
39
20 public class DuckSimulator {
40 [Link](new
21 public void Simulate(List<IQuackBehavior>
QuackCountDecorator(new
ducks){
OutputDecorator(new
22 foreach(IQuackBehaviour duck in ducks){
ReadHeadDuck())));
23 [Link]([Link]());
41 ...
24 }
42 }
25 }
43 }
26 }

76
© Paul Panhofer

1 //----------------------------------------- 6.4. Verhaltensmuster


2 // Entwurfsmuster: Dekorator
3 //----------------------------------------- Mit Verhaltensmustern können komplexe Interak-
4 public class Programm{ tionen zwischen Objekten modelliert werden.
5 public static void Main(String[] args){
6 List<IQuackBehavior> ducks = new
List<>(); 6.4.1 Verhaltensmuster - Command
7

8 [Link](new L Command
QuackCountDecorator(new
Das Command Muster erlaubt es eine Metho-
OutputDecorator(new
de wie ein Objekt zu verwenden.
ReadHeadDuck())));
9 [Link](new Damit wird es möglich Methodenobjekte in
QuackCountDecorator(new Warteschlangen zu stellen, Logbucheinträge
OutputDecorator(new zu führen bzw. die Auswirkungen der Metho-
MarbledDuck()))); de wieder rückgängig zu machen.
10

11 DuckSimualtor sim = new


DuckSimualtor(); Codebeispiel: Command
12 [Link](ducks); 1 //------------------------------------------
13 2 // Schnittstelle: ICommand
14 ConsoleWriteLn("quack count: " + 3 //------------------------------------------
[Link]); 4 // ICommand deklariert die Schnittstelle
15 } 5 // der Befehlsobjekte. Ein Befehlsobjekt kann
16 } 6 // durch das Aufrufen der execute() Methode
17 7 // aufgerufen werden.
18 > Ausgabe: 8 public interface ICommand{
19 9 void execute();
20 "Output: ... quack quack" 10 void undo();
21 "Output: ... qua qua qua" 11 }
22 "quack count: 2" 12

13 //------------------------------------------
14 // Klasse: ACommand

15 //------------------------------------------
16 public abstract class ACommand {
17

18 protected Robot _robot;


19

20 public ACommand(Robot robot) {


21 _robot = robot;
22 }
23

24 public abstract void Process();


25 public abstract void Undo();
26

27 }
28

29 //------------------------------------------
30 // Klasse: Point
31 //------------------------------------------
32 public class Point {
33 private int _x;
34 private int _y;

77
Softwareentwicklung

35 1 //------------------------------------------
36 public int X { 2 // Klasse: Robot
37 get => _x; 3 //------------------------------------------
38 set => _x = value; 4 public class Robot {
39 } 5

40 6 private Point _location = null;


41 public int Y { 7

42 get => _y; 8 public Point Location {


43 set => _y = value; 9 get => _location;
44 } 10 set => _location = value;
45 11 }
46 public Point(int x, int y) { 12 }
47 _x = x; 13

48 _y = y; 14 //------------------------------------------
49 } 15 // Klasse: MoveUpCommand
50 16 //------------------------------------------
51 public Point CalculateNeighbour( 17 public class MoveUpCommand : ACommand{
52 EDirectionType direction 18 public MoveUpCommand(Robot robot) :
53 ) { base(robot) { }
54 Point p = null; 19

55 20 public override void Process() {


56 switch (direction) { 21 _robot.Location =
57 case [Link]: 22 _robot.[Link](
58 p = new Point( 23 [Link]);
59 this._x, this._y + 1 24 }
60 ); 25

61 break; 26 public override void Undo() {


62 27 _robot.Location =
63 case [Link]: 28 _robot.[Link](
64 p = new Point( 29 [Link]);
65 this._x, this._y -1 30 }
66 ); 31 }
67 break; 32

68 33 //------------------------------------------
69 case [Link]: 34 // Klasse: MoveDownCommand
70 p = new Point( 35 //------------------------------------------
71 this._x -1, this._y 36 public class MoveDownCommand : ACommand{
72 ); 37 public MoveDownCommand(Robot robot) :
73 break; base(robot) { }
74 38

75 case [Link]: 39 public override void Process() {


76 p = new Point( 40 _robot.Location =
77 this._x + 1, this._y 41 _robot.[Link](
78 ); 42 [Link]);
79 break; 43 }
80 } 44

81 45 public override void Undo() {


82 return p; 46 _robot.Location =
83 } 47 _robot.[Link](
84 } 48 [Link]);
49 }
50 }

78
© Paul Panhofer

1 //------------------------------------------ 47 public bool Do() {


2 // Klasse: RemoteControl 48 if (_history.Count == 0)
3 //------------------------------------------ 49 return false;
4 public class RemoteControl { 50

5 51 ACommand command = _history.Pop();


6 private Stack<ACommand> _commands = new 52 [Link]();
Stack<ACommand>(); 53

7 private Stack<ACommand> _history = new 54 _commands.Push(command);


Stack<ACommand>(); 55

8 56 return true;
9 private Robot _robot; 57 }
10 58

11 public RemoteControl(Robot robot) { 59 public bool Redo() {


12 _robot = robot; 60 if (_commands.Count == 0)
13 } 61 return false;
14 62

15 public void MoveUp() { 63 ACommand command = _commands.Pop();


16 MoveUpCommand command = new 64 [Link]();
MoveUpCommand(_robot); 65

17 66 _history.Push(command);
18 _history.Clear(); 67 return true;
19 _commands.Push(command); 68 }
20 [Link](); 69 }
21 }
22 ❑
23 public void MoveDown() {
24 MoveDownCommand command = new
6.4.2 Verhaltensmuster - Strategy
MoveDownCommand(_robot);
25

26 _history.Clear(); L Strategy
27 _commands.Push(command); Das Strategie Muster ermöglicht es das Verhal-
28 [Link](); ten eines Objekts zur Laufzeit zu ändern. Für
29 } das Strategie Muster wird das Verhalten einer
30
Klasse in eine eigene Klasse ausgelagert.
31 public void MoveLeft() {
32 MoveLeftCommand command = new
Erklärung: Motivation und Kontext
MoveLeftCommand(_robot);
33
‚ Wir haben die Aufgabe den Warenkorb eines Web-
34 _history.Clear(); shops zu programmieren. Beim Bezahlen der Waren
35 _commands.Push(command); soll der Kunde mehrere Möglichkeiten für das Über-
36 [Link](); weisen des gewünschten Betrags haben.
37 } ‚ Der Bezahlvorgang wird als Strategie konzipiert und
38 kann dadurch bei jedem Bestellvorgang beliebig ge-
39 public void MoveRight() { wählt werden.
40 MoveRightCommand command = new
MoveRightCommand(_robot); Codebeispiel: Command
41 1 //------------------------------------------
42 _history.Clear(); 2 // Schnittstelle: IPaymentStrategy
43 _commands.Push(command); 3 //------------------------------------------
44 [Link](); 4 public interface IPaymentStrategy{
45 } 5 public void pay(int amount);
46 6 }

79
Softwareentwicklung

1 //------------------------------------------ 1 //------------------------------------------
2 // Klasse: CreditCardStrategy 2 // Klasse: Item
3 //------------------------------------------ 3 //------------------------------------------
4 public class CreditCardStrategy : 4 public class Item {
IPaymentStrategy{ 5

5 6 private string _upcCode;


6 private CreditCardProcessor processor = 7 private string _price;
new CreditCardProcessor(); 8

7 9 public UpcCode{
8 private string _cardNumber; 10 get => _upcCode;
9 private string _name; 11 }
10 12

11 public CreditCardStrategy(string name, 13 public Price{


string cardNumber){ 14 get => _price;
12 this._name = name; 15 }
13 this._cardNumber = cardNumber; 16

14 } 17 public Item(string upc, int cost){


15 18 this._upcCode = upc;
16 public void pay(int amount){ 19 this._price = cost;
17 [Link]( 20 }
18 _name, _cardNumber, amount 21 }
19 ); 22

20 } 23 //------------------------------------------
21 } 24 // Klasse: ShoppingCart
22 25 //------------------------------------------
23 //------------------------------------------ 26 public class ShoppingCart{
24 // Klasse: CreditCardStrategy 27

25 //------------------------------------------ 28 private List<Item> _items = new


26 public class PaypalStrategy : List<Item>();
IPaymentStrategy{ 29

27 30 private IPaymentStrategy _paymentMethod;


28 private PaypalProcessor processor = new 31

PaypalProcessor(); 32 public IPaymentStrategy PaymentMethod {


29 33 get => _paymentMethod;
30 private string _email; 34 set => _paymentMethod = value;
31 private string _pwd; 35 }
32 36

33 public PaypalStrategy(String email, 37 public void AddItem(Item item){


String pwd){ 38 _items.Add(item);
34 this._email = email; 39 }
35 this._pwd = pwd; 40

36 } 41 public int CalculateTotal(){


37 42 int sum = 0;
38 public void pay(int amount){ 43 foreach(var item in _items){
39 [Link]( 44 sum += [Link];
40 _email, 45 }
41 _pwd 46

42 ); 47 return sum;
43 } 48 }
44 }

80
© Paul Panhofer

1 public void Pay(){ .


2 int amount = CalculateTotal();
3 _paymentMethod.pay(amount);
4 }
5 }
6

7 //------------------------------------------
8 // Klasse: ShoppingCartUnitTest
9 //------------------------------------------
10 public class ShoppingCartUnitTest{
11

12 [Test]
13 public void Test(){
14 ShoppingCart cart = new ShoppingCart();
15

16 Item item1 = new Item("234", 10);


17 Item item2 = new Item("567", 30);
18

19 [Link] =
20 new PaypalStrategy(
21 "myemail@[Link]","mypwd"
22 );
23

24 [Link]();
25 }
26

27 }

81
.
Index
Architekturmuster, 54

Entwurfsmuster, 54

Idiom, 54

Singleton, 55

82

Das könnte Ihnen auch gefallen