• Keine Ergebnisse gefunden

252-0027 Einführung in die Programmierung 6.0 Objekte

N/A
N/A
Protected

Academic year: 2022

Aktie "252-0027 Einführung in die Programmierung 6.0 Objekte"

Copied!
86
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

252-0027

Einführung in die Programmierung

6.0 Objekte

Thomas R. Gross

Department Informatik ETH Zürich

Copyright (c) Pearson 2013 and Thomas R Gross 2016, 2017 All rights reserved.

(2)

Uebersicht

6.3 Parameter (Reference Type) 6.4 Konstruktoren

6.5 Noch ein Beispiel (Methoden) 6.6 Namesräume

6.7 static Methoden und Variablen 6.8 Module

Copyright (c) Pearson 2013. and Thomas Gross 2016 All rights reserved.

4

(3)

Point Klasse, Version 2

public class Point { int x;

int y;

public String toString() {

return "( " + x + ", " + y + " )";

}

public double distance() { // distance to (0, 0)

return Math.sqrt(x*x + y*y);

} } ...

(4)

Reference Semantics

§ Reference Variables die auf Objektexemplare

verweisen folgen den Reference Semantics Regeln

Point p1 = new Point();

p1.x = 3;

p1.y = 2;

Point p2 = p1; // p2.x == 3, p2.y == 2 p2.x = 4; // p2.x == 4, p2.y == 2 // p1.x == 4, p2.y == 2 p1 = null; // p1.x nicht zulaessig

6

(5)

9

(6)

Point Klasse, Version 2 Fortsetzung

public class Point { int x;

int y;

public String toString() {

return "( " + x + ", " + y + " )";

}

public double distance() { // distance to (0, 0)

return Math.sqrt(x*x + y*y);

}

public double distance(Point other) { // distance to other

return Math.sqrt((x-other.x)*(x-other.x)

+(y-other.y)*(y-other.y));

...}

(7)

Parameter Wiederholung

public class Parameter { public static void main

(String[] args) { int i = 1;

mOne(i);

System.out.

println("i = " + i);

}

}

public static void mOne(int x) { System.out.println("x = " + x);

x++;

System.out.println("x = " + x);

}

11

(8)

Parameter Wiederholung

public class Parameter { public static void main

(String[] args) { int i = 1;

mOne(i);

System.out.

println("i = " + i);

}

}

public static void mOne(int x) { System.out.println("x = " + x);

x++;

System.out.println("x = " + x);

}

12

x = 1 x = 2 i = 1

(9)

Value Semantics

13

main i: 1

mOne

(10)

Value Semantics

14

main i: 1

mOne 1

copy

(11)

Value Semantics

15

main i: 1

mOne 1

copy

(12)

Value Semantics

16

main i: 1

mOne x: 1 1

(13)

Value Semantics

17

main i: 1

mOne x: 2

(14)

Value Semantics

18

main i: 1

mOne x: 2

(15)

Parameter Uebergabe

§ Primitive Types: Kopieren, dann übergeben

§ Ein Buch (oder eine Festschrift) passen nicht in den Umschlag.

§ Buch: int[] book = new int[1000];

§ Festschrift:

class FestSchrift {

String author = "Famous";

int value = 1;

}

Festschrift feS = new FestSchrift(); 19

(16)

Parameter

public class Parameter { public static void main

(String[] args) { FS feS = new FS();

mTwo(feS);

System.out.

println("Author = " + feS.author + " " + feS.value);

} }

public static void mTwo(FS x) {

System.out.println("Author = " + x.author + " " + x.value);

x.value++;

x.author = "Nobody";

System.out.println("Author = " + x.author + " " + x.value);

}

20

(17)

Parameter

public class Parameter { public static void main

(String[] args) { FS feS = new FS();

mTwo(feS);

System.out.

println("Author = " + feS.author + " " + feS.value);

} }

public static void mTwo(FS x) {

System.out.println("Author = " + x.author + " " + x.value);

x.value++;

x.author = "Nobody";

System.out.println("Author = " + x.author + " " + x.value);

}

21

Author = Famous 1 Author = Nobody 2 Author = Nobody 2

(18)

Reference Semantics

22

main feS:

mTwo

(19)

Reference Semantics

23

main feS:

mTwo Famous

1

(20)

Reference Semantics

24

mTwo Famous

1

KF 456 ….

copy main

feS:

(21)

Reference Semantics

26

feS

Famous 1

(22)

Reference Semantics

27

mTwo Famous

1

KF 456 ….

copy main

feS:

(23)

Reference Semantics

28

mTwo Famous

1

KF 456 ….

main feS:

(24)

Reference Semantics

29

mTwo Famous

1

x:

main feS:

(25)

Reference Semantics

30

Nobody 2

x main

feS:

mTwo x:

(26)

Reference Semantics

31

mTwo Nobody

main 2

feS: x:

(27)

Reference Semantics

§ Ist der Parameter eine Referenzvariable, so wird diese kopiert und an die aufgerufene Methode übergeben

§ Das Argument (in der aufrufenden Methode) und der Parameter (in der aufgerufenen Methode) verweisen beide auf das selbe Objekt.

§ Aenderungen des Objektes sind in der aufrufenden Methode sichtbar

§ Gilt für Exemplare von Klassen und für Arrays

32

(28)

Parameter

public class Parameter { public static void main

(String[] args) { FS feS = new FS();

mThree(feS);

System.out.

println("Author = " + feS.author + " " + feS.value);

} }

public static void mThree(FS x) { System.out.println("Author = " +

x.author + " " + x.value);

x = new FS();

x.author = "Hero";

System.out.println("Author = " + x.author + " " + x.value);

}

33

(29)

Parameter

public class Parameter { public static void main

(String[] args) { FS feS = new FS();

mThree(feS);

System.out.

println("Author = " + feS.author + " " + feS.value);

} }

public static void mThree(FS x) { System.out.println("Author = " +

x.author + " " + x.value);

x = new FS();

x.author = "Hero";

System.out.println("Author = " + x.author + " " + x.value);

}

34

Author = Famous 1 Author = Hero 1 Author = Famous 1

(30)

Reference Semantics

35

mThree Famous

main 1

feS: x:

(31)

Reference Semantics

36

mThree Famous

1 Hero

main 1

feS: x:

(32)

Reference Semantics

§ Ist der Parameter eine Referenzvariable, so wird diese kopiert und an die aufgerufene Methode übergeben

§ Das Argument (in der aufrufenden Methode) und der Parameter (in der aufgerufenen Methode) verweisen beide auf das selbe Objekt.

§ Aenderungen des Objektes sind in der aufrufenden Methode sichtbar

§ Aenderungen der Referenzvariable sind in der aufrufenden Methode nicht sichtbar

§ Wenn Sie die Bibliothekskarte eines Buches ändern so bleibt das Buch unverändert

37

(33)

Java Methodenaufruf

§ In Java werden also Referenzvariable und Variable eines Basistyps immer kopiert.

§ Die Entwickler haben darauf keinen Einfluss.

§ Andere Programmiersprachen erlauben mehr Flexibilität. Für jeden Parameter kann bestimmt werden, wie er übergeben wird.

§ Viele Fehler sind möglich ….

38

(34)

Uebersicht

6.3 Parameter (Reference Type) 6.4 Konstruktoren

6.5 Noch ein Beispiel (Methoden) 6.6 Namesräume

6.7 static Methoden und Variablen 6.8 Module

Copyright (c) Pearson 2013. and Thomas Gross 2016 All rights reserved.

39

(35)

Konstruktion und Initialisierung von Objekten

§ Der new Operator liefert eine Referenz (einen Verweis) auf ein neues Objekt

§ new class(): Exemplar (Instanz) der Klasse class

§ new class[size]: Array der Länge size für Referenzen auf Exemplare der Klasse class

Vergleiche mit:

§ new int[size]: Array der Länge size für int Werte

(36)

Initialisierung von Objekten

§ Bisher waren mehrere Anweisungen nötig, um ein Exemplar einer Klasse zu konstruieren und es zu initialisieren:

Point p = new Point();

p.x = 3;

p.y = 8;

§ (N+1) Anweisungen bei N Attributen

§ Lange Folgen von Anweisungen

§ Leicht etwas zu übersehen

(37)

Initialisierung von Objekten

§ Besser wäre es die Werte für die Attribute gleich anzugeben:

Point p = new Point(3, 8); // better!

Person employee = new Person("Paula", 123);

§ Wir können so etwas für viele Arten von Objekten in Java machen.

(38)

Konstruktoren

§ Konstruktor (“constructor”): Initialisiert den Zustand eines neuen Objektes.

public type(parameters) { statements;

}

§ Ausgeführt wenn der new Operator ausgeführt wird

§ Es gibt keinen Rückgabewert.

§ Im Rumpf können beliebige Anweisungen auftreten (wie in Methode)

(39)

Konstruktoren

§ Ein Konstruktor ist keine Methode

§ Konstruktoren sind optional

§ Wenn eine Klassendefinition keinen Konstruktor enthält, dann stellt Java einen (voreingestellten) default Konstruktor (“default

constructor”) zur Verfügung

§ Der default Konstruktor hat keine Parameter und setzt alle Felder auf Null (entweder 0, 0.0, oder null)

(40)

Beispiele von Konstruktoren

public class Point { int x;

int y;

// Constructs a Point at the given x/y location.

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

// Methods ...

}

(41)

Beispiele von Konstruktoren

public class Person { String name;

int id;

double hourlyRate;

double [] hours;

double [] overtime;

// Constructs a Person with given name and Id public Person(String firstname, int uniqueId) {

name = firstname;

id = uniqueId;

}

// Methods ...

}

(42)

Konstruktor

§ Attribute, die nicht in einem Konstruktor auf einen Wert

gesetzt werden, werden auf Null gesetzt (0, 0.0, or null).

§ Beispiel:

public Point (int initialX) { x = initialX;

}

Point p1 = new Point(7);

// p1.y == 0

47

(43)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

(44)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

public void setLocation(int newX, int newY) {

x y

p1

(45)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

public void setLocation(int newX, int newY) {

x 0 y 0

p1

(46)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

public void setLocation(int newX, int newY) {

x 7 y 0

p1

(47)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

public void setLocation(int newX, int newY) {

x 7 y 2

p1

(48)

Ausführung eines Konstruktors in Zeitlupe

§ Was passiert wenn dieser Code ausgeführt wird?

Point p1 = new Point(7, 2);

public Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

public void setLocation(int newX, int newY) {

x 7 y 2

p1

(49)

Mehrere Konstruktoren

§ Eine Klasse kann mehrere Konstruktoren haben.

§ Jeder Konstruktor muss eine unverwechselbare Liste von Parametern haben

§ Entscheidend ist dass die Typen der Parameterliste unverwechselbar sind

§ Erlaubt

public Point(int initialX, int initialY) { x=initialX; y=initialY; } public Point(int initialX) {x = nitialX; y = 0;}

§ Nicht erlaubt

public Point(int initialX, int initialY) { x=initialX; y=initialY; } public Point(int a, int b) { x = a; y = b; }

(50)

§ Schreiben Sie einen Point Konstructor ohne Parameter der den Punkt mit (0, 0) initialisiert.

// Constructs a new point at (0, 0).

public Point() { x = 0;

y = 0;

}

58

(51)

Häufige Fehler in Konstruktoren

1. (Erneute) Deklaration von Attributen als Variable:

public Point(int initialX, int initialY) { int x = initialX;

int y = initialY;

}

§ Jetzt gibt es Variable x und y die nur im Konstruktor bekannt sind.

Diese erhalten einen Wert – aber die Attribute werden nicht modifiziert und bleiben 0.

(52)

Häufige Fehler in Konstruktoren

2. Versehentlich für den Konstruktor einen Rückgabewert deklarieren:

public void Point(int initialX, int initialY) { x = initialX;

y = initialY;

}

§ Nicht die Definition eines Konstruktors sondern die Definition einer Methode mit Namen Point

(53)

Häufige Fehler mit Konstruktoren

3.) Den parameterlosen default Konstruktor verwenden wenn andere Konstruktoren definiert wurden und kein

parameterloser Konstruktor definiert wurde.

class Point { int x; int y;

public Point(int initialX, int initialY) { … } // methods

}

// in the client

Point p = new Point(); 61

(54)

Uebersicht

6.3 Parameter (Reference Type) 6.4 Konstruktoren

6.5 Noch ein Beispiel (Methoden) 6.6 Namesräume

6.7 static Methoden und Variablen 6.8 Module

62

(55)

Ein Problem: Teilfolgen finden

§ Gegen sei ein Folge S der Länge n (S0, S1, …, Sn-1) wobei jedes Si aus einem (endlichen) Alphabet gewählt ist.

§ Eine Folge T der Länge m heisst Teilfolge von S, wenn es m aufsteigend sortierte Indizes i0, i1, ..., im-1 gibt so dass Sik = Tk für k = 0, …, (m-1).

§ Beispiel:

§ S = ABCDE, T = ACD: (i0,i1,i2) = (0,2,3)

§ S = ABCDC, T = BDC: (i0,i1,i2) = (1,3,4) 63

(56)

Teilfolgen finden

§ Schreiben Sie ein Programm, dass für eine Folge S und eine nicht-negative ganze Zahl j alle Teilfolgen der Länge j von S bestimmt.

64

(57)

Beispiele

§ S = abcd, j = 3

abc abd bcd acd

§ S = abcd, j = 5

§ S = abcd, j = 0

leerer String ("")

§ S = accb, j = 2

ac ac ab cc cb cb

65

(58)

Teilfolgen finden

§ Folge: als (Java) String dargestellt. Alphabet: Default Alphabet der Java Implementation.

§ nicht-negative ganze Zahl: int

§ Schreiben Sie ein Programm, dass einen String S und eine nicht-negative ganze Zahl j einliest und alle Teilfolgen der Länge j ausgibt.

66

(59)

Teilfolgeprobleme

§ Gemeinsame Teilfolgen

§ Längste gemeinsame Teilfolgen

§ Folgen von DNA, RNA, Protein Molekülen …

67

(60)

68

(61)

69

(62)

Rahmen

import java.util.Scanner;

public class Subsequence {

public static void main(String[] args) {

Scanner console = new Scanner(System.in);

System.out.print("Input string (no spaces):");

String str = console.next();

System.out.print("Length of subsequences:");

int subseqLength = console.nextInt();

// … unser Programm } // main

} 70

(63)

Ansatz

1. Finden von Indexfolgen i0, i1, i2, …, ij-1

a. Alle ausprobieren

b. Zufällige (Index)Folgen generieren

§ Speichern ob schon ausgegeben

§ Neue geben entsprechenden String aus

2. Mit Strings (direkt) arbeiten

§ Indices treten nicht direkt in Erscheinung

73

(64)

74

a b c d

Länge 1

(65)

75

a b c d

Länge 1

a b c d

(66)

76

a b c d

Länge 2

a b c d

(67)

77

a b c d

Länge 2 a

a b c d b c d

(68)

78

a b c d

Länge 2 a

a b c d b c d

b

a b c d c d

(69)

79

a b c d

Länge 2 a

a b c d b c d

b

a b c d c d

c

a b c d d

(70)

80

a b c d

Länge 2 a

a b c d b c d

b

a b c d c d

c

a b c d d ab ac ad bc bd cd

(71)

81

a b c d e f g h u v w x y z

Länge j

a b c d e f g h u v w x y z a b c d e f g h u v w x y z String Länge s

(gebildet aus diesem Teil von str, einem Prefix von str)

String Länge (s+1) (gebildet aus dem Prefix von str) + g

Brauchen String Länge (j-s) gebildet aus dem Rest

Brauchen String Länge (j-s-1) gebildet aus dem Rest

(72)

82

a b c d e

Länge 3

a b c d e a b c d e String Länge 1

(gebildet aus diesem Teil von str, einem Prefix von str)

String Länge 2 (gebildet aus dem Prefix von str) + b

Brauchen String Länge 2 gebildet aus dem Rest

Brauchen String Länge 1 gebildet aus dem Rest

a b c d e String Länge 3

(gebildet aus dem Prefix von str) + c

Brauchen String Länge 0 gebildet aus dem Rest

(73)

Lösungs(anfang)

§ Wenn wir einen String P haben und noch 0 Zeichen (aus dem unverarbeiteten Rest) dazu fügen müssen, dann haben wir ein Teilfolge mit j Zeichen gefunden.

§ Wir fangen an mit P dem leeren String, t = j (Anzahl Zeichen) die wir noch brauchen, und der Rest ist der Eingabestring.

83

(74)

Lösungs(anfang)

§ Wenn wir einen String P haben und noch 0 Zeichen (aus dem unverarbeiteten Rest) dazu fügen müssen, dann haben wir ein Teilfolge mit j Zeichen gefunden.

§ Wir fangen an mit P dem leeren String, t = j (Anzahl Zeichen) die wir noch brauchen, und der Rest ist der Eingabestring.

§ Wenn wir einen String P der Länge s haben (s<j, d.h. wir

brauchen noch j-s Buchstaben aus dem Rest) dann nehmen wir den 1. Buchstaben des Rests, konkatenieren ihn mit P und machen weiter (d.h. brauchen noch j-s-1 Buchstaben, neuer Rest ist der alte Rest ohne den 1. Buchstaben). 84

(75)

Lösungs(anfang)

§ Wenn wir einen String P der Länge s haben (s<j, d.h. wir

brauchen noch j-s Buchstaben aus dem Rest) dann nehmen wir den 1. Buchstaben des Rests, konkatenieren ihn mit P und machen weiter (d.h. brauchen noch j-s-1 Buchstaben, neuer Rest ist der alte Rest ohne den 1. Buchstaben).

§ Wenn der Rest leer ist dann können wir mit diesem String P nicht weiter arbeiten

85

(76)

86

a b c

Länge 4

a b c a b c String Länge 1

String Länge 2

Brauchen String Länge 3 gebildet aus dem Rest "bc"

Brauchen String Länge 2 gebildet aus dem Rest "c"

a b c

String Länge 3 Brauchen String Länge 1

gebildet aus dem Rest ""

(77)

87

a b c d e f g h u v w x y z

Länge j

a b c d e f h u v w x y z a b c d e f g h u v w x y z String Länge s

(gebildet aus diesem Teil von str, einem Prefix von str)

String Länge s

Brauchen String Länge (j-s)

gebildet aus dem Rest "g h u … "

Brauchen String Länge (j-s)

gebildet aus dem Rest "h u v … "

(78)

a b c d e

Länge 3

a c d e a b c d e String Länge 1

(gebildet aus diesem Teil von str, einem Prefix von str)

String Länge 1

Brauchen String Länge 2 gebildet aus dem Rest

Brauchen String Länge 2 gebildet aus dem Rest

(79)

Lösung (weiter)

Wenn wir einen String P der Länge s haben (s<j, d.h. wir

brauchen noch j-s Buchstaben aus dem Rest, Rest nicht leer)

1. Wir nehmen den 1. Buchstaben des Rests, konkatenieren ihn mit P und machen weiter (d.h. brauchen noch j-s-1

Buchstaben, neuer Rest ist der alte Rest ohne den 1.

Buchstaben)

2. Wir finden die j-s Buchstaben im Rest ohne den 1.

Buchstaben (d.h., wir brauchen immer noch j-s Buchstaben, neuer Rest ist der alte Rest ohne den 1. Buchstaben)

89

(80)

90

(81)

Lösung

import java.util.Scanner;

public class Subsequence {

public static void main(String[] args) {

Scanner console = new Scanner(System.in);

System.out.print("Input string (no spaces):");

String str = console.next();

System.out.print("Length of subsequences:");

int subseqLength = console.nextInt();

findSubSequence("", str, subseqLength) } // main

91

(82)

public static void findSubSequence(String prefix, String remaining, int target) {

// target: characters needed to reach desired subsequence length

if (target == 0) {

System.out.println(prefix);

return;

}

if (!remaining.isEmpty()) {

findSubSequence(prefix + remaining.charAt(0),

remaining.substring(1), target-1);

findSubSequence(prefix, remaining.substring(1), target);

}

} //findSubSequence 92

(83)

public static void findSubSequence(String prefix, String remaining, int target) {

// target: characters needed to reach desired subsequence length

if (target == 0) {

System.out.println(prefix);

return;

}

if (!remaining.isEmpty()) {

findSubSequence(prefix + remaining.charAt(0),

remaining.substring(1), target-1);

findSubSequence(prefix, remaining.substring(1), target);

}

} //findSubSequence 93

(84)

public static void findSubSequence(String prefix, String remaining, int target){

for (int i=0; i<prefix.length(); i++) { System.out.print(" ");

}

System.out.println("Prefix \"" + prefix + "\" Remaining \""

+ remaining + "\" Target=" + target);

if (target == 0) {

System.out.println(prefix);

return;

}

if (!remaining.isEmpty()) {

findSubSequence(prefix + remaining.charAt(0), remaining.substring(1), target-1);

findSubSequence(prefix, remaining.substring(1), target);

}

} 94

mit Log/Trace

(85)

Input string (no spaces):abcd Length of subsequences:3

input = abcd 3

Prefix "" Remaining "abcd" Target=3 Prefix "a" Remaining "bcd" Target=2

Prefix "ab" Remaining "cd" Target=1 Prefix "abc" Remaining "d" Target=0 abc

Prefix "ab" Remaining "d" Target=1 Prefix "abd" Remaining "" Target=0 abd

Prefix "ab" Remaining "" Target=1 Prefix "a" Remaining "cd" Target=2

Prefix "ac" Remaining "d" Target=1 Prefix "acd" Remaining "" Target=0 acd

Prefix "ac" Remaining "" Target=1 Prefix "a" Remaining "d" Target=2

Prefix "ad" Remaining "" Target=1 95

Log

(86)

Prefix "a" Remaining "" Target=2 Prefix "" Remaining "bcd" Target=3

Prefix "b" Remaining "cd" Target=2 Prefix "bc" Remaining "d" Target=1

Prefix "bcd" Remaining "" Target=0 bcd

Prefix "bc" Remaining "" Target=1 Prefix "b" Remaining "d" Target=2

Prefix "bd" Remaining "" Target=1 Prefix "b" Remaining "" Target=2 Prefix "" Remaining "cd" Target=3

Prefix "c" Remaining "d" Target=2 Prefix "cd" Remaining "" Target=1 Prefix "c" Remaining "" Target=2 Prefix "" Remaining "d" Target=3

Prefix "d" Remaining "" Target=2 Prefix "" Remaining "" Target=3

96

Log

Referenzen

ÄHNLICHE DOKUMENTE

§ Programm: Folge von Anweisungen, die von einem Computer ausgeführt werden (können).. § Programm realisiert

§ Eine Referenzvariable (“reference type variable”, Variable eines Referenztyps) erlaubt den Zugriff auf einen Array (ein Objekt)..

§ Alle Methoden einer Klasse können auf eine static Variable zugreifen. § Gemeinsame (&#34;shared&#34;) Variable für

§ Schiedsrichter entscheidet ob das Symbol legal ist oder nicht (für diese EBNF Beschreibung)2. § Symbol legal gemäss einer Regel: alle Buchstaben des Symbols stimmen mit den

§ Wir wollen einer Methode erlauben, einen Array (oder ein Objekt) als Parameter zu erhalten ohne dass die.. Arrayelemente kopiert

Den Code dieser Klasse können Sie nicht sehen, aber sie enthält eine Methode void rotateArray(int[] values, int steps), welche Sie aus einer eigenen Klasse oder einem Unit-Test

§ Wenn eine Methode einen Parameter erwartet dann muss dieser auch übergeben werden. printPunkte(); // ERROR: parameter value

3.)  Den  parameterlosen  default  Konstruktor  verwenden  wenn   andere  Konstruktoren  definiert  wurden  und  kein  . parameterloser  Konstruktor