WEBVTT

00:07.400 --> 00:09.860
Herzlich willkommen zurück zur Programmiervorlesung.

00:11.140 --> 00:14.540
Sie erinnern sich, wir waren in der letzten Vorlesung schon im Bereich

00:14.540 --> 00:18.880
Typen und Variablen und sind dann da auf der Folie 10 stehen

00:18.880 --> 00:22.440
geblieben, aber damit Sie so nach einem längeren Wochenende diversen

00:22.440 --> 00:26.440
Übungsblättern der Mathematik wieder den Einstieg finden, nochmal ganz

00:26.440 --> 00:29.340
kurz, was bisher geschah, für die, die jetzt erst einschalten.

00:30.060 --> 00:33.360
Also, wir haben über Datentypen gesprochen.

00:34.400 --> 00:37.080
Letzten Endes ist es, wenn man sich Zahlen anschaut, eine Art

00:37.080 --> 00:42.040
Wertebereich und dann können einzelne Werte davon Zustand einer

00:42.040 --> 00:42.900
Variablen sein.

00:42.980 --> 00:45.570
Eine Variable hat einen Datentyp, wir hatten Beispiele kennengelernt,

00:46.000 --> 00:52.000
Zahlen, Ganzzahlen, Integer, wir hatten Wahrheitswerte kennengelernt,

00:53.080 --> 00:57.000
für einen Wahrheitswert, also nur True oder False, das ist Boolean

00:57.000 --> 01:00.660
gewesen und wir werden heute noch einige weitere kennenlernen.

01:02.020 --> 01:08.300
Wir hatten Operatoren auf diesen Zahlentypen uns angeschaut, hatten

01:08.300 --> 01:10.860
die auch kurz besprochen, die meisten sind von denen wahrscheinlich

01:10.860 --> 01:13.260
für sie relativ intuitiv naheliegend.

01:14.160 --> 01:17.420
Es gab auch logische Operatoren, die auf Bitwerten oder

01:17.420 --> 01:20.380
Wahrheitswerten operieren, das ist vielleicht nicht ganz so intuitiv,

01:20.880 --> 01:21.840
das hatten wir uns angeschaut.

01:21.840 --> 01:29.540
Wir hatten uns die Verknüpfungen angeschaut von Bedingungen, also auch

01:29.540 --> 01:32.420
logische Wahrheitswerte mit und und oder, wir haben uns über

01:32.420 --> 01:38.020
Präzedenz, also Klammerungsregeln Gedanken gemacht, hatten uns für die

01:38.020 --> 01:40.840
bitweisen Operatoren und auch für die logischen Operatoren mal diese

01:40.840 --> 01:45.160
Wahrheitstabelle angeschaut, hatten dann über die ganzen Zahlen

01:45.160 --> 01:48.200
gesprochen, was es hier auch für Sorgen gibt, nämlich über den

01:48.200 --> 01:55.840
Unterlauf und hatten ganz zuletzt in der Vorlesung über die Inkrement-

01:55.840 --> 02:00.280
und Dekrementoperatoren gesprochen, und zwar ob die vor der Auswertung

02:00.280 --> 02:03.820
einer Variable, von dem Lesen einer Variable ausgeführt werden oder

02:03.820 --> 02:04.280
danach.

02:04.420 --> 02:07.340
Deswegen haben wir das Präfix, das heißt z.B.

02:07.380 --> 02:11.860
der Wert wird erniedrigt oder erhöht, bevor der Wert weitergereicht

02:11.860 --> 02:15.220
wird oder Postfixoperator, das heißt also mit Plus, Plus oder Minus,

02:15.300 --> 02:19.080
Minus hinten, dass der Wert nachher verarbeitet wird, nachdem er

02:19.080 --> 02:19.680
ausgelesen wird.

02:21.360 --> 02:26.940
So, wo wir dann stehen geblieben sind, war genau diese Stelle, und

02:26.940 --> 02:28.600
hier steigen wir jetzt wieder in die Vorlesung ein.

02:28.720 --> 02:32.780
Jetzt eben hatten wir die ganzen Zahlen, wie man weiß, die natürlichen

02:32.780 --> 02:36.380
Zahlen sind von Gott gemacht, alles andere ist Menschenwerk, das hat

02:36.380 --> 02:40.120
schon Frege gesagt, und genauso ist es ein bisschen auch für uns

02:40.120 --> 02:40.780
Informatiker.

02:40.780 --> 02:46.080
Also, ganze Zahlen darstellen ist insofern erstmal für uns relativ

02:46.080 --> 02:48.800
natürlich, weil wir können eine binäre Präsentation wählen, die ist im

02:48.800 --> 02:49.780
Computer abspeicherbar.

02:50.100 --> 02:52.780
Die einzige Sorge, die wir halt haben, das ist mit der Unendlichkeit,

02:53.140 --> 02:55.920
das hatten wir auch besprochen, daher eben ein Überlauf.

02:56.720 --> 03:00.080
Ich kann immer nur endlich viele Variablen, verschiedene Werte in den

03:00.080 --> 03:02.960
Variablen abspeichern, aufgrund schlicht und ergreifend auch der

03:02.960 --> 03:04.000
Endlichkeit des Computers.

03:04.440 --> 03:07.040
Und wenn ich halt eben zu hohe Werte habe für einen Wertebereich, dann

03:07.040 --> 03:08.240
gibt es halt einen Überlauf.

03:09.360 --> 03:12.320
In den Fließkomma-Zahlen ist die Sache deutlich trickreicher.

03:13.560 --> 03:17.420
Und hier ist es so, man könnte ja sagen, wenn ich jetzt mit Komma

03:17.420 --> 03:20.380
-behafteten Zahlen abspeichern will, wie kann ich das machen?

03:20.860 --> 03:24.720
Naja, ich könnte ja sagen, ich definiere immer eigentlich zwei Integer

03:24.720 --> 03:26.020
-Werte und dazwischen ist halt ein Komma.

03:26.100 --> 03:29.420
Das kann ich machen, ist aber im gewissen Sinne Platzverschwendung.

03:29.520 --> 03:32.900
Und was man sich mal überlegt hat, ist eher ein optimiertes Verfahren,

03:32.980 --> 03:40.360
wo man sagt, ich teile den Speicherbedarf zwischen möglichst großen

03:40.360 --> 03:43.600
Zahlen, die ich darstellen will, und auch möglichst exakter

03:43.600 --> 03:47.480
Darstellung einer Zahl, die sehr viele Nachkommastellen hat.

03:47.720 --> 03:50.260
Das möchte ich sehr variabel aufteilen und ich möchte nicht immer

03:50.260 --> 03:53.460
pauschal zum Beispiel sehr viel Platz auch für kleine Zahlen

03:53.460 --> 03:56.540
verwenden, nur um potenziell große Zahlen darzustellen und ich möchte

03:56.540 --> 03:58.620
auch nicht für Zahlen, die vielleicht nur ein oder zwei

03:58.620 --> 04:01.800
Nachkommastellen haben, unheimlich viel Speicherplatz reservieren, um

04:01.800 --> 04:03.520
die Nachkommastellen alle darzustellen.

04:04.220 --> 04:06.880
Und aus dieser Sorge heraus, dass man sagt, ich möchte in dem Sinne

04:06.880 --> 04:11.520
ein angepasstes Speicherformat haben für Zahlen, wo ich beides kann,

04:11.640 --> 04:15.040
sehr große Zahlen darstellen, aber eben auch sehr präzise Zahlen

04:15.040 --> 04:18.640
darstellen kann, also mit einem hohen Nachkommabereich, kam man auf

04:18.640 --> 04:21.920
die Idee, sogenannte Gleitkommazahlen zu machen, das heißt, wo das

04:21.920 --> 04:24.800
Komma eben nicht an einer festen Stelle sitzt, sondern je nach Bedarf

04:24.800 --> 04:25.940
rotieren kann.

04:25.940 --> 04:28.220
Das ist eben nicht immer an der fünften Stelle oder so.

04:30.440 --> 04:36.240
Und das ist an einem Standard, der IEEE, das ist dieses IEEE, was Sie

04:36.240 --> 04:38.140
hier sehen, festgelegt worden.

04:38.200 --> 04:43.780
Das ist eine Berufsorganisation, eigentlich heißt es International

04:43.780 --> 04:50.040
Association of Electrical and Electronical Engineers, spricht aber

04:50.040 --> 04:52.980
keiner so aus, Sie sehen auch ich holpere, also IEEE sagt man kurz

04:52.980 --> 04:56.080
dazu, und das ist eine Organisation, die eben mitunter neben vielen

04:56.080 --> 05:00.120
anderen Dingen auch Standards herausgibt und ein Standard legt mal

05:00.120 --> 05:03.340
fest, wie stellt man Gleitkommazahlen dar.

05:03.740 --> 05:06.360
Ich will gar nicht auf den Standard im Einzelnen dargehen, sondern

05:06.360 --> 05:08.240
eigentlich die Idee hier darstellen.

05:08.940 --> 05:13.120
Und zwar sagt man, eine Zahl x kann ich immer darstellen, als

05:13.120 --> 05:17.120
Vorzeichen behaftet oder nicht, mathematisch kann man natürlich diesen

05:17.120 --> 05:19.120
Trick machen, den kennen Sie aus der höheren Mathematikvorlesung

05:19.120 --> 05:24.880
sicherlich schon, Minus 1 hoch, wenn hoch 0 ist 1, hoch 1 ist Minus 1,

05:25.000 --> 05:27.220
damit kann ich immer das Minus 1 ausschalten, wenn ich so will.

05:28.640 --> 05:36.640
Einer Mantisse, das ist dieses M hier und einem Exponenten.

05:37.460 --> 05:41.780
Und jetzt das Ganze so, kann man das nicht so vorstellen, wenn ich z

05:41.780 --> 05:41.820
.B.

05:41.860 --> 05:47.320
das Vorzeichen hier auf 1 setze, also Minus 1 hoch 1, Exponent auf

05:47.320 --> 05:53.940
Minus 1 mal Minus 1 und M gleich 5 ergibt sich daraus, wenn ich das

05:53.940 --> 06:01.260
alles einsetze, Minus 1 hoch 1 mal 5 mal 2 hoch Minus 1, da kommt also

06:01.260 --> 06:05.900
diese Minus 1 rein, dann habe ich eben die Zahl Minus 2,5 dargestellt.

06:05.900 --> 06:09.040
Das zeigt also jetzt hier das Zusammenspiel, ich habe einen

06:09.040 --> 06:12.660
Exponenten, der kann aber negativ sein und damit schaffe ich es,

06:13.380 --> 06:15.360
flapsig gesprochen, Kommazahlen darzustellen.

06:17.100 --> 06:21.260
Und ich habe eine Mantisse, die im Prinzip dann dafür zuständig ist,

06:21.260 --> 06:22.580
überhaupt erstmal den Wert anzugeben.

06:22.680 --> 06:27.460
Und Sie sehen, das Elegante in diesem Format ist, ich mache jetzt

06:27.460 --> 06:30.640
nicht unbedingt eine Festlegung, dass ich eine feste Zahl von Stellen

06:30.640 --> 06:33.500
immer vor einem Komma habe oder nach einem Komma, sondern es ergibt

06:33.500 --> 06:35.400
sich im Prinzip durch Berechnung dieser Formel erst.

06:36.020 --> 06:38.440
Und das Ergebnis ist genau das, was ich Ihnen gesagt hatte.

06:39.280 --> 06:42.120
Wir haben jetzt hier ein Zahlenformat gefunden, mit dem ich auf der

06:42.120 --> 06:44.900
einen Seite sehr große Zahlenwerte darstellen kann, einfach wenn ich

06:44.900 --> 06:49.560
zum Beispiel einen Exponenten wähle, 2 hoch einer positiven Zahl, mal

06:49.560 --> 06:51.780
multipliziert kann ich natürlich hohe Zahlenbereiche erreichen.

06:52.180 --> 06:54.880
Genauso, wenn ich eben negativen Exponenten habe, dann kann ich

06:54.880 --> 06:57.760
natürlich auch sehr kleine Zahlenwerte darstellen und sehr präzise.

06:57.760 --> 07:01.100
Das ist jetzt mal ganz grob die Idee von einem Gleitkommastandard.

07:01.460 --> 07:04.360
Und IEEE ist der, der meistens verwendet wird, auch in Java.

07:06.320 --> 07:08.820
Und intern werden diese Darstellungen so dargestellt, eben wie hier

07:08.820 --> 07:10.240
Vorzeichen, Mantisse, Exponent.

07:11.340 --> 07:16.400
Für uns als Nutzer dieser Sprache ist eigentlich jetzt diese

07:16.400 --> 07:19.420
Aufteilung in Mantisse und Exponent gar nicht so wichtig.

07:19.540 --> 07:24.200
Wir können die Zahl direkt angeben, wie wir eine Dezimalzahl eben

07:24.200 --> 07:24.940
eingeben würden.

07:24.940 --> 07:27.860
Ganz normal, mit Dezimalpunkt.

07:29.720 --> 07:32.900
Was Sie aber verstehen müssen, ist halt, intern wird es letztendlich

07:32.900 --> 07:35.260
immer in dieses Format umgerechnet und dadurch können natürlich

07:35.260 --> 07:37.120
besondere Probleme entstehen.

07:37.680 --> 07:42.120
Es ist eben nur, wenn man so will, eine Approximation an das Konzept

07:42.120 --> 07:44.360
der reellen Zahlen, wie Sie das aus der Mathematik kennen.

07:44.360 --> 07:51.220
Es ist natürlich zum einen klar, wenn Sie eine Zahl haben, die

07:51.220 --> 07:58.420
unendlich viele Nachkommastellen hat, also eine Zahl wie z.B.

07:58.520 --> 08:02.160
Pi oder E, eine Naturkonstante oder auch sowas wie Wurzel 2, die eben

08:02.160 --> 08:06.380
nicht periodisch wird, dann hat man natürlich das Problem, ich habe

08:06.380 --> 08:09.960
auch wieder nicht die Möglichkeit im Computer, das mit der exakten

08:09.960 --> 08:12.860
Präzision darzustellen, weil ich natürlich irgendwann abbrechen muss,

08:12.920 --> 08:14.320
ich habe nicht unendlich viel Speicherplatz.

08:16.200 --> 08:19.300
Und so kann es auch hier passieren, in diesen Zahlen, dass ich z.B.

08:19.920 --> 08:22.960
Rechenoperationen durchführe, die mathematisch gesehen nicht z.B.

08:23.020 --> 08:26.360
auf 0 kommen, sondern auf einen kleinen Wert, aber hier ich das nicht

08:26.360 --> 08:27.460
präzise darstellen kann und z.B.

08:27.460 --> 08:28.100
auf 0 komme.

08:28.580 --> 08:31.380
Oder umgedreht kann das sein, dass ich Rundungsfehler habe, die

08:31.380 --> 08:33.220
dadurch entstehen, wenn ich jetzt mit diesen Gleitkommazahlen

08:33.220 --> 08:36.240
rumrechne, die dafür sorgen, dass ich dann eben doch nicht exakt den

08:36.240 --> 08:38.740
richtigen Wert darstelle bei mir, weil ich eben auch doch nur eine

08:38.740 --> 08:41.220
begrenzte Genauigkeit habe und das Ergebnis werden wir z.B.

08:41.340 --> 08:42.300
nachher noch sehen, wenn ich z.B.

08:42.980 --> 08:43.460
Zahlenvergleiche mache.

08:43.560 --> 08:46.000
Ich kann das nicht einfach auf Gleichheit vergleichen wie bei den

08:46.000 --> 08:49.220
Integerzahlen, bei den ganzen Zahlen, sondern hier muss ich immer nur

08:49.220 --> 08:51.660
schauen, dass der Unterschied möglichst klein ist, aber das werden wir

08:51.660 --> 08:52.180
jetzt gleich sehen.

08:54.380 --> 08:56.120
Was gibt es jetzt für besondere Werte?

08:57.440 --> 08:59.620
Einmal NAN, not a number.

09:01.040 --> 09:03.360
Das ist dann, wenn im Prinzip versucht wird, etwas in eine

09:03.360 --> 09:06.280
Gleitkommazahl umzurechnen, was aber nicht umrechenbar ist in einer

09:06.280 --> 09:07.020
Gleitkommazahl.

09:09.460 --> 09:12.500
Dann positive infinity, negative infinity.

09:13.240 --> 09:16.140
Das sind Werte, wenn es im Prinzip über den darstellbaren

09:16.140 --> 09:20.020
Zahlenbereich hinausgeht, dann werden diese Werte reingeschrieben, im

09:20.020 --> 09:21.340
positiven wie im negativen Sinne.

09:23.900 --> 09:27.620
Plus 0,0, minus 0,0 sind im Prinzip auch darstellbare Zahlen.

09:28.680 --> 09:31.060
Mathematische Operationen werden gerundet, wie ich eben gesagt habe.

09:31.700 --> 09:38.620
Und es gibt in Java eine vordefinierte Klasse Math, die schon typische

09:38.620 --> 09:42.020
Gleitkomma -Operatoren vordefiniert hat.

09:43.160 --> 09:45.740
Absolutwert, Sinus, Cosinus, Quadratwurzel und so weiter.

09:47.160 --> 09:48.740
Dann kommen wir noch zu den Sachen mit der Gleichheit.

09:48.860 --> 09:53.160
Das hatte ich Ihnen schon mal auch in der Vorlesung vorher gesagt.

09:54.860 --> 09:57.660
So würde man das bei Integer-Zahlen hinschreiben.

09:58.120 --> 10:00.760
x gleich gleich y, damit würde man sie auf Gleichheit vergleichen.

10:01.440 --> 10:03.900
Wenn die beiden jetzt denselben Wert haben, geben wir True raus.

10:04.600 --> 10:08.420
Das macht bei Gleitkommazahlen wenig Sinn, weil es mit Rundungsfehlern

10:08.420 --> 10:09.360
behaftet sein kann.

10:09.460 --> 10:12.540
Und wir meinen eigentlich ist es gleich und es sollte gleich sein.

10:13.120 --> 10:16.100
Und wir möchten das tun, was wir tun wollen, wenn diese Zahlen gleich

10:16.100 --> 10:16.320
sind.

10:16.740 --> 10:19.120
Aber der Computer würde durch den exakten Vergleich der Zahlen eben

10:19.120 --> 10:20.160
sagen, nein, die sind nicht gleich.

10:20.900 --> 10:25.860
Und was man besser macht, ist also den Absolutwert der Differenz zu

10:25.860 --> 10:28.320
nehmen und dann zu schauen, dass der zum Beispiel kleiner ist als ein

10:28.320 --> 10:28.940
bestimmter Wert.

10:31.340 --> 10:37.020
Und mit EO-8 ist der Exponent minus 8 gemeint.

10:39.200 --> 10:42.200
Und dasselbe halt für Ungleichvergleich, dass man sagt, das muss

10:42.200 --> 10:44.000
größer sein als dieser Wert.

10:44.380 --> 10:48.540
Das ist mal ein Wert, der sich so eingebürgert hat, quasi als Epsilon

10:48.540 --> 10:51.340
-Wert, also als kleiner Wert, wo man sagt, gegen den vergleiche ich

10:51.340 --> 10:52.820
und wenn es kleiner ist, sage ich jetzt doch 0.

10:55.400 --> 10:57.540
Das sind auch die Fließkomma-Zahlen.

10:58.500 --> 11:00.740
Als Datentyp kommen wir zum nächsten, und zwar Zeichen.

11:01.300 --> 11:06.500
Jetzt gibt es den, weil ihr habt den Namen Character abgekürzt, Char,

11:07.400 --> 11:07.960
was hier steht.

11:08.800 --> 11:11.400
Und damit kann ich ein Zeichen abspeichern, wenn man so will.

11:11.480 --> 11:13.160
Erstmal grob gesagt ein Buchstaben.

11:13.900 --> 11:15.640
Was heißt das jetzt konkret, ein Buchstaben?

11:15.640 --> 11:25.480
Dazu gibt es verschiedene Kodierungen, die letzten Endes festlegen,

11:26.500 --> 11:28.680
welchen Binär-Code hat ein Buchstabe.

11:29.180 --> 11:32.380
Sie erinnern sich, Computer können immer nur binäre Werte speichern.

11:33.780 --> 11:36.260
Für Integer-Zahlen ist das relativ angenehm, weil eine Integer-Zahl

11:36.260 --> 11:38.080
hat natürlich immer eine binäre Darstellung.

11:38.600 --> 11:40.260
Für ein Buchstaben ist das natürlich erst mal nicht so klar.

11:40.260 --> 11:41.900
Welche binäre Darstellung hat ein A?

11:42.160 --> 11:44.660
Das kann man sich jetzt nicht logisch erschließen, das muss man mal

11:44.660 --> 11:45.560
festlegen.

11:46.020 --> 11:49.180
Und da gibt es eine Reihe von Standards, die sich im Laufe der

11:49.180 --> 11:50.880
Geschichte der Informatik herausgebildet haben.

11:51.540 --> 11:55.220
Ein relativ stark verbreiteter, aber heute veralteter ist der ASCII

11:55.220 --> 12:00.740
-Standard, der im Prinzip versucht, in einem Byte 256 verschiedene

12:00.740 --> 12:02.260
Zeichen festzulegen und zu kodieren.

12:04.980 --> 12:08.740
Und da sind die Buchstaben drin, das passt natürlich letztlich rein,

12:09.080 --> 12:11.960
weil ich habe natürlich 26 große und 26 kleine Buchstaben, plus noch

12:11.960 --> 12:13.320
ein paar Sonderbuchstaben wie SZ.

12:13.900 --> 12:16.200
Und ich kann also noch ein paar mehr Zeichen kodieren da rein, das

12:16.200 --> 12:16.780
macht man auch.

12:18.960 --> 12:20.780
Prozentzeichen, Anführungsstriche, alles mögliche sind natürlich auch

12:20.780 --> 12:23.220
noch an Zeichen drin, im Wesentlichen das, was Sie auf der Tastatur

12:23.220 --> 12:23.560
finden.

12:25.320 --> 12:27.900
Irgendwann hat man mal gemerkt, das reicht nicht aus, in einem Byte

12:27.900 --> 12:30.800
256 Zeichen, das klingt vielleicht viel für Leute mit einem

12:30.800 --> 12:34.780
lateinischen Alphabet, aber es gibt natürlich Alphabete, wo man mehr

12:34.780 --> 12:35.940
Buchstaben hat.

12:37.340 --> 12:40.340
Außerdem ist es natürlich so, dass ich vielleicht auch noch weitere

12:40.340 --> 12:42.900
Zeichen darstellen kann, und nicht nur eben Buchstaben.

12:43.620 --> 12:47.280
Und dann ist vor einigen Jahren der sogenannte Unicode entstanden, der

12:47.280 --> 12:50.620
mit zwei Bytes das Ganze kodiert und damit also wesentlich mehr

12:50.620 --> 12:51.840
Zeichen erlaubt.

12:53.220 --> 12:56.680
Also wie gesagt, Character, wir stellen erstmal ein Zeichen dar, und

12:56.680 --> 12:59.320
es ist die Frage, wie lege ich denn jetzt den Wert von dem Zeichen

12:59.320 --> 12:59.580
fest.

12:59.680 --> 13:01.960
Klar, ich könnte direkt den Binärcode eintippen, das ist aber wieder

13:01.960 --> 13:03.540
ein bisschen unhandlich für uns als Programmierer.

13:03.640 --> 13:06.420
Wenn wir sagen wollen, dieses Zeichen hier soll der Buchstabe A

13:06.420 --> 13:08.860
gespeichert sein, dann wollen wir ja nicht selber erst im Standard als

13:08.860 --> 13:11.700
Mensch nachgucken, was ist denn jetzt der Binärstring für A und das

13:11.700 --> 13:15.400
dann in den Wert da eintragen, sondern wir möchten natürlich in der

13:15.400 --> 13:17.540
Lage sein zu sagen, okay, das ist ein A.

13:18.000 --> 13:22.680
Und das macht man so, dass man das hier in so Hochzeichen setzt, und

13:22.680 --> 13:25.800
dann könnte man eben das einer Variable vom Typ Character zuweisen.

13:26.940 --> 13:30.140
Man kann natürlich auch, also nicht nur Buchstaben, sondern zum

13:30.140 --> 13:35.120
Beispiel auch eine Zahl dem zuweisen, aber Achtung, das ist jetzt im

13:35.120 --> 13:39.660
Prinzip das Zeichen 3, und das Zeichen 3 hat einen anderen Typ als der

13:39.660 --> 13:40.640
Integerwert 3.

13:40.740 --> 13:44.120
Mit dem Integerwert 3 können Sie rumrechnen, mit Buchstaben können Sie

13:44.120 --> 13:44.940
erstmal nicht rechnen.

13:45.340 --> 13:47.740
Mit Buchstaben kann man ein anderes machen, man kann die

13:47.740 --> 13:50.580
aneinanderhängen und kann Wörter damit zum Beispiel bilden, aber man

13:50.580 --> 13:52.380
kann mit Buchstaben per se nicht rechnen.

13:52.920 --> 13:55.900
Ich weiß, es gibt hier eine sehr hohe Fraktion von C-Programmierern,

13:56.320 --> 14:00.380
die wissen, das kann man natürlich heimlicherweise schon, aber in Java

14:00.380 --> 14:03.620
ist die Welt noch in Ordnung, deswegen müssen sie in Java auch nicht

14:03.620 --> 14:05.640
ganz so einen starken Charakter haben wie als C-Programmierer.

14:05.940 --> 14:08.540
In Java ist es so, mit Buchstaben kann man gewisse Sachen machen,

14:08.700 --> 14:09.260
andere nicht.

14:09.820 --> 14:12.040
Man kann Buchstaben aneinanderhängen, das macht Sinn, wenn man aus

14:12.040 --> 14:13.040
Buchstaben Wörter haben will.

14:14.120 --> 14:15.780
Man kann aber mit Buchstaben nicht rechnen.

14:15.780 --> 14:18.560
Mit Integer-Zahlen kann man hingegen rechnen, man kann sie

14:18.560 --> 14:20.040
multiplizieren, dividieren usw.

14:20.460 --> 14:21.700
Und das ist jetzt genau der Unterschied.

14:21.980 --> 14:25.760
Eine 3 als Zahl ist etwas anderes als eine 3 als Zeichen.

14:25.880 --> 14:28.480
Und wenn ich eine 3 als Zeichen meine, dann stelle ich sie eben in

14:28.480 --> 14:29.580
diese Hochkommata.

14:33.520 --> 14:38.140
Jetzt kann es ja sein, dass Sie besondere Zeichen darstellen wollen,

14:38.280 --> 14:40.940
die man so in der Form nicht tippt.

14:41.120 --> 14:42.720
Zum Beispiel einen Zeilenwechsel.

14:42.720 --> 14:46.160
Wenn Sie sagen möchten, ich möchte eine neue Zeile anfangen bei der

14:46.160 --> 14:50.300
Ausgabe einer Botschaft, dann gibt es dieses Slash n.

14:51.680 --> 14:53.260
Was sagt also bitte eine Zeile weiter?

14:54.220 --> 14:57.680
Und damit man jetzt sagt, ich meine nicht das Zeichen n, sondern einen

14:57.680 --> 15:00.900
Zeilenwechsel, macht man noch diesen Slash, diesen Schrägstrich davor.

15:03.920 --> 15:07.320
Und das sind sogenannte Escape-Sequenzen.

15:07.320 --> 15:12.200
Das ist jetzt an sich nicht so wichtig, dass Sie erklären können,

15:12.320 --> 15:14.160
warum der Begriff Escape-Sequenz Sequenz heißt.

15:14.260 --> 15:17.260
Escape heißt letztendlich, ich komme aus dem Modus, dass ich eine

15:17.260 --> 15:19.560
Zeichenkette angebe, wieder raus.

15:20.740 --> 15:24.960
Und zwar soll das einfach nur heißen, ich kann jetzt ein besonderes

15:24.960 --> 15:28.200
Zeichen an der Stelle innerhalb einer normalen Zeichenkette einfügen.

15:29.200 --> 15:33.520
Und wenn Sie ein n nur reingeben, dann würden Sie natürlich einfach

15:33.520 --> 15:35.360
nur sagen, das soll der Buchstabe n sein.

15:35.780 --> 15:38.080
Wenn Sie aber sagen möchten, ich meine einen Zeilenwechsel, dann geben

15:38.080 --> 15:39.300
Sie eben Backslash n an.

15:40.300 --> 15:42.120
Dasselbe Problem hat man jetzt natürlich auch mit dem Apostroph.

15:42.200 --> 15:44.700
Das Apostroph sagt ja, jetzt kommt ein Zeichen.

15:44.800 --> 15:48.520
Wenn ich aber das Apostroph selber als Zeichen meine, sehen Sie, haben

15:48.520 --> 15:49.080
Sie jetzt ein Problem.

15:49.180 --> 15:51.420
Sie können schlecht drei Apostrophs hintereinander machen.

15:52.720 --> 15:54.960
Aber letzten Endes müsste man ja sowas der Art machen.

15:55.040 --> 15:57.880
Und dann macht man eben auch diesen Backslash dann davor.

15:58.780 --> 16:01.940
Und wenn man also eine Zeichenkette hat, ich male das mal gerade auf.

16:04.580 --> 16:09.960
Also wenn Sie eine Zeichenkette haben wollen, wo Sie einen Doppel

16:09.960 --> 16:12.240
-Apostroph haben, dann schreiben Sie eben auch so einen Backslash

16:12.240 --> 16:12.580
davor.

16:13.340 --> 16:16.960
Wenn Sie ein Zeichen haben wollen mit einem einzelnen Apostroph, dann

16:16.960 --> 16:18.160
schreiben Sie auch einen Backslash davor.

16:18.340 --> 16:21.420
Weil wie gesagt, sonst wäre im Prinzip das ganze A nicht lesbar und B

16:21.420 --> 16:22.120
auch sehr verwirrend.

16:22.180 --> 16:25.380
Wenn Sie jetzt sowas hätten und weiß der Rechner nicht, ist das jetzt

16:25.380 --> 16:29.060
das leere Zeichen hier damit gemeint und dann kommt nochmal so ein

16:29.060 --> 16:29.820
einzelnes hinterher.

16:29.820 --> 16:31.000
Das ist halt dann nicht ganz klar.

16:31.720 --> 16:35.700
Und deswegen halt immer, wenn Sie innerhalb eines Zeichens oder einer

16:35.700 --> 16:38.800
Zeichenkette operieren und ein Sonderzeichen meinen, dann schreibt man

16:38.800 --> 16:39.880
eben diesen Backslash.

16:39.960 --> 16:41.060
Das ist der Querstrich davor.

16:42.920 --> 16:46.840
Damit können Sie jetzt auch Konstanten angeben.

16:47.880 --> 16:49.880
Oktal oder Hexadezimal, das hatten wir gesehen.

16:49.960 --> 16:52.560
Es gibt natürlich verschiedene Zahlensysteme, um Zahlen darzustellen.

16:52.560 --> 17:00.000
Und das können Sie mit dem vorgestellten Groß-O oder O-U machen für

17:00.000 --> 17:01.120
Oktal oder Hexadezimal.

17:01.700 --> 17:04.460
Wenn Sie den Backslash selber darstellen wollen, auch das könnte man

17:04.460 --> 17:07.660
ja wollen, dann ist es insofern auch nur logisch, dass es dann zwei

17:07.660 --> 17:08.520
Backslash sind.

17:09.460 --> 17:13.840
So, jetzt ein Zeichen alleine.

17:21.240 --> 17:24.800
Wenn Sie jetzt die Zeichen so in diesen Anführungszeichen darstellen,

17:25.020 --> 17:29.380
ist das natürlich finalerweise wieder eine Zahl und jetzt können Sie

17:29.380 --> 17:30.920
auch gewisse Operatoren darauf anwenden.

17:31.060 --> 17:33.740
Sie können also jetzt eins darauf erhöhen und dann haben Sie im

17:33.740 --> 17:36.500
Prinzip wieder eine Zahl erreicht oder Sie multiplizieren.

17:37.600 --> 17:43.460
Aber wenn Sie jetzt hier zum Beispiel statt dem A eine 3 drin haben,

17:43.560 --> 17:49.360
dann ist natürlich 3 in Anführungszeichen plus 1 nicht 4, sondern Sie

17:49.360 --> 17:51.780
haben den Zahlenwert von 3 als Zeichen.

17:51.900 --> 17:54.400
Was das ist, müsste man im ASCII-Code nachschauen.

17:54.900 --> 17:58.200
Wenn Sie 1 dazu addieren, dann haben Sie eben den um 1 erhöhten Wert

17:58.200 --> 17:58.720
davon.

17:59.000 --> 18:03.120
Aber es ist eben nicht 3 plus 1, sondern es ist 3 als Zeichen, welcher

18:03.120 --> 18:04.920
Wert das ist und dann plus 1.

18:06.820 --> 18:10.880
So, ein Zeichen alleine hilft einem jetzt auch nicht so viel, sondern

18:10.880 --> 18:12.620
letzten Endes werden wir mit Texten umgehen.

18:13.020 --> 18:16.420
Und dafür gibt es dann einen Datentyp, der heißt Zeichenkette oder im

18:16.420 --> 18:17.240
Englischen String.

18:18.840 --> 18:20.760
Und das ist auch in Java vordefiniert.

18:20.860 --> 18:22.040
Es gibt eine Klasse, die heißt String.

18:22.820 --> 18:24.560
Und hier sehen Sie mal so ein paar Beispiele.

18:27.480 --> 18:30.580
Ich habe hier ein Objekt von der Klasse String definiert.

18:30.660 --> 18:33.180
Das heißt Text und weise dem auch tatsächlich einen Text zu.

18:33.180 --> 18:34.020
Und das ist ein Text.

18:37.460 --> 18:42.340
Und ein weiterer Zeichenkette wäre so ein Greeting.

18:42.820 --> 18:48.480
Da gebe ich Hallo ein und die Adresse am Fasanengarten.

18:48.620 --> 18:51.600
Und jetzt sehen Sie das hier, kommt dieser Backslash N.

18:52.120 --> 18:54.420
Das heißt einfach hier Zeilenumbruch unter.

18:54.840 --> 18:57.600
Das heißt also hier an der Stelle soll eine neue Zeile anfangen und

18:57.600 --> 18:58.400
das steht dann da drunter.

19:01.100 --> 19:04.440
So und was kann ich jetzt mit diesen Zeichenketten, mit diesen Strings

19:04.440 --> 19:04.820
machen?

19:06.400 --> 19:08.700
Ich kann zum Beispiel zwei aneinanderhängen.

19:08.820 --> 19:10.280
Das passiert mit dem Plus-Operator.

19:11.520 --> 19:13.760
Das heißt also dieses Plus hier ist nicht eine Addition.

19:14.600 --> 19:15.020
Warum nicht?

19:15.100 --> 19:17.600
Naja, weil hier keine Zahlenwerte links und rechts stehen, sondern

19:17.600 --> 19:18.600
hier steht eine Zeichenkette.

19:18.940 --> 19:21.600
Und ich könnte sagen, ein einzelnes Zeichen hat vielleicht noch einen

19:21.600 --> 19:23.420
Wert, den ich in der Tabelle nachkriegen kann.

19:25.280 --> 19:28.020
Aber definitiv, eine Zeichenkette hat in dem Sinne keinen Wert.

19:28.020 --> 19:31.560
Also kann ich hier nichts mit Addition rechnen, sondern heißt schlicht

19:31.560 --> 19:35.420
und ergreifend, ich hänge diese beiden Zeichenketten hier mit dem Plus

19:35.420 --> 19:38.220
beieinander und dann steht hier eben dieses eine Konkatenation.

19:39.240 --> 19:43.960
Oder ich könnte zum Beispiel sagen, ich hänge das Hallo und dann daran

19:43.960 --> 19:47.280
am Fasanengarten fünf neue Zeilen Karlsruhe.

19:47.480 --> 19:52.920
Und das wäre dann hier das Ganze so, diese zwei Objekte konkateniert.

19:53.860 --> 19:55.940
Das Ergebnis würde ich dann hierzu weisen.

19:59.300 --> 20:04.080
Und damit sind wir jetzt auf unseren Reigen der Datentypen erstmal an

20:04.080 --> 20:05.060
der Stelle fast durch.

20:05.760 --> 20:12.620
Es gibt noch einen und das ist die sogenannte Enumeration.

20:12.980 --> 20:15.640
Daher kommt das Enumeration, Aufzählung.

20:15.840 --> 20:22.420
Und damit kann ich mir selber eine Reihe von, wenn man so will, einen

20:22.420 --> 20:25.040
Datentyp schaffen, der mit eigenen Werten, die ich selber definiere,

20:25.220 --> 20:25.700
auch bearbeitet.

20:25.700 --> 20:26.940
Was heißt das am Beispiel?

20:27.080 --> 20:28.360
Ich glaube, dann wird es leichter verständlich.

20:29.000 --> 20:32.820
Zum Beispiel sage ich hier, ich habe die Richtung eines Kompasses und

20:32.820 --> 20:36.380
das ist Norden, Osten, Süden, Westen.

20:36.580 --> 20:39.860
Und Sie sehen also diese vier Werte, die ich selber jetzt auch hier

20:39.860 --> 20:44.360
definiert habe, Norden, Osten, Süden, Westen, definieren den

20:44.360 --> 20:47.340
Wertebereich eines neuen Datentyps, der heißt Kompass Direction.

20:47.500 --> 20:49.700
Das heißt mit anderen Worten, Kompass Direction kann auch gar keinen

20:49.700 --> 20:53.160
anderen Wert annehmen als die vier Werte, die ich jetzt hier dahinter

20:53.160 --> 20:53.980
definiert habe.

20:53.980 --> 20:57.880
Man könnte mal sagen, alles für Elefants, wozu braucht man sowas?

20:58.960 --> 21:01.380
Ohne sowas kann ich ja auch programmieren und das stimmt.

21:02.100 --> 21:04.620
Aber Sie erinnern sich an meine Aussage, die ich schon in der ersten

21:04.620 --> 21:05.580
Vorlesung gemacht habe.

21:06.560 --> 21:09.720
Es kommt immer sehr stark auf die Lesbarkeit Ihres Programms an.

21:09.880 --> 21:12.180
Sie schreiben das Programm insbesondere für den nächsten Menschen, der

21:12.180 --> 21:12.840
es lesen muss.

21:13.860 --> 21:17.460
Und natürlich könnten Sie ja auch sagen, ich bin richtig cool, ich

21:17.460 --> 21:18.740
programmiere jetzt im Binärcode.

21:19.920 --> 21:21.040
Ich bin so drauf.

21:21.460 --> 21:22.200
Klar, das geht.

21:22.320 --> 21:24.760
Für den Computer ist es genau dasselbe, als wenn Sie das in Java

21:24.760 --> 21:25.340
programmieren.

21:26.180 --> 21:28.100
Finalerweise wird ja auch das Java, wie Sie es gelernt haben,

21:28.260 --> 21:29.200
umgesetzt in Binärcode.

21:29.340 --> 21:31.540
Aber für den nächsten Menschen, der es lesen muss, ist es natürlich

21:31.540 --> 21:31.800
ein Riesenunterschied.

21:33.160 --> 21:35.080
So, und wenn Sie sich jetzt mal so überlegt haben, dass in Java

21:35.080 --> 21:37.140
programmieren vielleicht doch ein bisschen menschenfreundlicher ist,

21:37.140 --> 21:39.600
als irgendwie im Binärcode hinschreiben, dann würden Sie vielleicht,

21:39.660 --> 21:41.500
wenn Sie diesen Gedankengang mal weitergehen, auch vielleicht

21:41.500 --> 21:45.580
einsehen, dass es natürlich Sinn macht, solche vordefinierten

21:45.580 --> 21:50.600
Enumerations zu verwenden, weil damit wieder mehr Begrifflichkeiten

21:50.600 --> 21:55.700
aus der Anwendungswelt, also aus der Problemwelt, der Welt, was das

21:55.700 --> 21:59.360
Programm machen soll, übertragen wird in die Lösungswelt.

21:59.500 --> 22:01.280
Und das ist ja das, was ich Ihnen auch eingangs in der letzten

22:01.280 --> 22:02.060
Vorlesung sage.

22:02.460 --> 22:05.880
Ein gut dokumentiertes Programm versucht immer, demjenigen, der es

22:05.880 --> 22:09.220
liest, klarzumachen, was passiert hier eigentlich im Sinne der

22:09.220 --> 22:11.400
Anwendungswelt, da wo das Problem herkommt.

22:12.000 --> 22:15.080
Und eben nicht alles nur runtergezogen in eine Lösungswelt.

22:15.080 --> 22:17.740
Wie gesagt, in der Lösungswelt können Sie beliebig schlampige und

22:17.740 --> 22:22.200
schlechte Variablen-Namen geben, können Sie T1, XYZ machen, alles

22:22.200 --> 22:22.520
prima.

22:22.960 --> 22:26.000
In dem Augenblick, wo aber jemand das lesen soll, hilft es fürs

22:26.000 --> 22:30.380
Verständnis natürlich viel mehr, wenn Sie statt X plus Y gleich Z

22:30.380 --> 22:35.180
hinschreiben, zum Beispiel Abbuchung plus Zahlungsangang ist gleich

22:35.180 --> 22:35.800
Kontostand.

22:35.920 --> 22:37.320
Dann haben Sie gleich viel mehr gelesen.

22:38.000 --> 22:40.480
Mathematisch gesehen ist es natürlich dasselbe wie X plus Y gleich Z.

22:41.420 --> 22:44.500
In diesem Sinne hier Enumerations auch hier wieder die Möglichkeit,

22:45.300 --> 22:49.140
Konzepte aus der Anwendungswelt mit ins Programm reinzunehmen, um

22:49.140 --> 22:50.600
einfach das Verständnis zu erhöhen.

22:51.120 --> 22:53.680
Das nächste Beispiel ist auch relativ selbstsprechend.

22:53.960 --> 22:56.680
Sie definieren hier einen Datentyp Tag, auch wieder einen

22:56.680 --> 23:01.180
Aufzählungstyp, der als Werte die verschiedenen Namen der Tage haben

23:01.180 --> 23:01.480
kann.

23:02.540 --> 23:04.920
Und natürlich könnten Sie sagen, ich definiere jetzt mal für mich

23:04.920 --> 23:08.200
Montag ist 0, Dienstag ist 1, Mittwoch ist 3 usw.

23:09.460 --> 23:11.420
Sonntag ist 2, Donnerstag ist 3 usw.

23:11.520 --> 23:15.080
Nur der Witz ist, wenn Sie das einmal gemacht haben und nachher

23:15.080 --> 23:21.180
feststellen müssen, aus irgendeinem Grund in meinem Programm möchte

23:21.180 --> 23:28.120
ich vielleicht von einem 5% Gewinnaufschlag auf 6% gehen und jetzt

23:28.120 --> 23:30.740
muss ich alle Fünfen ändern, werden Sie spätestens bei der Fünf, die

23:30.740 --> 23:33.920
dann da irgendwo den Freitag anzeigt, überlegen muss ich die jetzt

23:33.920 --> 23:34.640
auch ändern oder nicht.

23:34.740 --> 23:36.040
Die Antwort ist natürlich nicht, die hat nämlich mit dem

23:36.040 --> 23:37.040
Gewinnaufschlag nichts zu tun.

23:37.040 --> 23:39.220
Das war nämlich die Fünf, die den Freitag markiert.

23:40.160 --> 23:42.020
Und genau dieses Verständnis haben Sie natürlich nicht, wenn Sie da

23:42.020 --> 23:43.000
einfach nur Fünf reinschreiben.

23:43.100 --> 23:44.220
Eine Fünf kann erstmal alles heißen.

23:44.700 --> 23:47.260
Und dann müssen Sie sehr lange nachdenken, die Programmcode lesen, was

23:47.260 --> 23:48.280
wird mit dieser Fünf gemacht.

23:48.400 --> 23:50.680
Ist das jetzt die Fünf, die den Gewinnaufschlag bedeutet hat oder ist

23:50.680 --> 23:51.480
das eine andere Fünf?

23:51.880 --> 23:54.900
Ja, diese ganzen Sachen entledigen Sie sich, wenn Sie beim Schreiben

23:54.900 --> 23:58.200
einfach hinschreiben, Sie nehmen einen Aufzählungsdatentyp und die

23:58.200 --> 23:59.100
Fünf heißt jetzt Friday.

23:59.420 --> 24:01.700
Und dann ist klar, was dieser Wert bedeutet.

24:01.860 --> 24:03.080
Das ist der Name eines Tages.

24:04.900 --> 24:07.980
Und an dieser Stelle eine ganz banale Sache, die ich schon selber als

24:07.980 --> 24:10.540
Student gelernt habe hier in Karlsruhe von meinem Softwaretechnik

24:10.540 --> 24:10.980
-Professor.

24:11.200 --> 24:13.180
Keine Angst vor langen Variablennamen.

24:13.540 --> 24:16.060
Diese einfache Botschaft sollte sich Ihnen hoffentlich genauso in das

24:16.060 --> 24:16.900
Hirn schreiben wie mir.

24:18.380 --> 24:20.580
Sie schreiben einmal diesen Variablennamen hin.

24:20.680 --> 24:23.560
Da wird, wenn Sie Pech haben, mehrfach gelesen, mehrfach rätseln Leute

24:23.560 --> 24:26.760
drüber, was meinte der bloß mit diesem Variablennamen, wenn denn der

24:26.760 --> 24:31.300
Variablenname T1 ist oder XB-Hilfe oder so ein Quatsch.

24:31.300 --> 24:34.020
Da kann man ziemlich lange drüber nachdenken, was war damit gemeint.

24:34.440 --> 24:37.840
Wohingegen, wenn da eben ein ausdrucksvoller Name steht, habe ich

24:37.840 --> 24:40.220
natürlich von vornherein allen Lesern das Leben leichter gemacht, ich

24:40.220 --> 24:42.080
hatte nur einmal etwas mehr Aufwand beim Tippen.

24:46.270 --> 24:49.410
So, Operatoren auf Aufzählungsdatentypen reden wir jetzt noch nicht

24:49.410 --> 24:51.370
drüber, kommt in der späteren Vorlesung dran.

24:54.110 --> 24:56.830
So, und an der Stelle machen wir ein kleines Quiz.

24:57.730 --> 25:01.210
Mal gerade Hand hoch, wer hat kein Smartphone oder kein Laptop mit

25:01.210 --> 25:02.390
Internetzugang dabei?

25:03.710 --> 25:07.310
Genau, dann gucken Sie bitte bei Ihrem Nachbarn rein, der das nämlich

25:07.310 --> 25:07.870
offenbar hat.

25:09.410 --> 25:15.390
Und zwar, Hintergrund von so einer Übung ist, ich weiß immer hier, 14

25:15.390 --> 25:17.950
Uhr ist ein bisschen schlecht, ich kämpfe immer so ein bisschen gegen

25:17.950 --> 25:22.710
das gerade verdauende Mensaessen an und so ein bisschen Interaktivität

25:22.710 --> 25:26.270
hilft vielleicht, sich leichter mit den Lehrinhalten vertraut zu

25:26.270 --> 25:26.350
machen.

25:26.350 --> 25:29.810
Das weiß man übrigens auch aus Didaktikforschung, je aktiver Sie

25:29.810 --> 25:35.310
teilnehmen hier und interagieren, desto leichter lernen Sie die

25:35.310 --> 25:36.310
Inhalte, die ich hier vermittle.

25:36.790 --> 25:42.890
Also was Sie hier sehen, ist eine URL, msocreative.com, M für Leute,

25:42.990 --> 25:44.190
die auf dem Mobilgerät arbeiten.

25:44.910 --> 25:48.270
Wenn Sie auf dem Desktop Internetverbindung haben, können Sie auch www

25:48.270 --> 25:49.530
.socreative.com eingeben.

25:49.530 --> 25:54.090
Das ist eine Cloud-basierte Lösung, wo Sie jetzt für das Quiz, was ich

25:54.090 --> 25:56.610
jetzt gleich vorstelle, das beantworten können.

25:56.670 --> 26:01.290
Und wir sehen dann hier interaktiv, wie Sie antworten und welche

26:01.290 --> 26:03.970
Meinung es quasi hier verteilt über die Hörer gibt.

26:04.410 --> 26:07.370
Jetzt können Sie sagen, Cloud-basierte Lösung, das ist doch nicht

26:07.370 --> 26:07.610
sicher.

26:07.730 --> 26:10.350
Wer weiß, welcher Geheimdienst oder welche bösen Mächte hier mithören.

26:10.810 --> 26:13.030
Ja klar, ist mir bekannt, aber ich meine, dass Karlsruher Studenten

26:13.030 --> 26:14.610
schlau sind und immer das Richtige antworten.

26:14.750 --> 26:15.750
Also das wissen wir ja eh schon.

26:17.310 --> 26:24.690
So, jetzt werden Sie hier gebeten, einen Raumnamen sozusagen

26:24.690 --> 26:25.450
anzugeben.

26:26.010 --> 26:28.830
Und den Raumnamen, der jetzt für uns, für unsere Lehrveranstaltungen

26:28.830 --> 26:33.490
hier jetzt und heute gilt, ist PROG1415.

26:34.590 --> 26:36.670
Alle anderen deutschen Universitäten haben natürlich jetzt ein Pech

26:36.670 --> 26:37.610
für ihren Programmierkurs.

26:37.750 --> 26:40.130
Den Namen haben wir am KIT schon weggeschnappt, aber wir waren halt

26:40.130 --> 26:41.130
die Ersten.

26:42.130 --> 26:48.030
Und wenn Sie das gemacht haben, also an dieser Stelle PROG1415

26:48.030 --> 26:56.050
eingeben und dann sagen Enter oder Join Room, dann sollten Sie schon

26:56.050 --> 26:57.990
gleich die erste Frage sehen.

26:58.450 --> 27:01.390
Also das sind die Fragen, machen wir vielleicht erstmal so rum.

27:01.450 --> 27:04.190
Das sind die Fragen, die Sie jetzt gleich sehen werden, wenn Sie

27:04.190 --> 27:05.450
online eingeloggt sind.

27:05.450 --> 27:06.730
Und zwar erstmal die erste Frage.

27:09.030 --> 27:16.990
Und das ist die Frage, warum ist der Wert von 10 Dächelchen 6 nicht 1

27:16.990 --> 27:18.470
Million, sondern 12?

27:18.610 --> 27:19.390
Das ist die Frage.

27:22.390 --> 27:27.730
Das ist also das, was Sie auch als Frage sehen sollten, wenn Sie sich

27:27.730 --> 27:29.410
jetzt eingeloggt haben in diesem Socrative-System.

27:29.550 --> 27:31.630
Also ich habe das jetzt in einer Lehreransicht gemacht.

27:32.470 --> 27:35.610
Das ist diese Raumnummer und das ist die Frage, die Sie jetzt sehen

27:35.610 --> 27:35.910
sollten.

27:36.030 --> 27:36.590
Jetzt schauen wir mal.

27:37.990 --> 27:40.550
Ich bin zum Glück noch im Internet drin und bin nicht rausgeflogen.

27:42.470 --> 27:44.930
Und immerhin, genau, prima.

27:46.290 --> 27:48.530
Es haben schon 42 von Ihnen geantwortet.

27:49.590 --> 27:52.890
Nicht wieder ausloggen, es gibt ja Fragen noch danach, also wenn Sie

27:52.890 --> 27:55.070
die Frage beantwortet haben, einfach da bleiben.

27:56.530 --> 27:59.070
Ich mache es jetzt mal kurz, weil wir haben ja noch weitere Fragen.

28:00.850 --> 28:03.550
Ich bin jetzt nicht so nett, ich sage jetzt nicht Show Names.

28:18.090 --> 28:19.890
Also ich mache es mal kurz.

28:21.750 --> 28:25.070
Wer war bei Auffassung Überlauf, sei die Antwort.

28:25.070 --> 28:28.550
Ja, das ist wenige.

28:29.190 --> 28:31.630
Das ist eigentlich gut, weil das ist so ein bisschen der Trick bei der

28:31.630 --> 28:32.010
Frage.

28:32.670 --> 28:38.070
Man liest als Mensch dieses Dach hier natürlich mal schnell gerne als

28:38.070 --> 28:38.570
hoch.

28:38.850 --> 28:39.690
6 hoch 10.

28:39.830 --> 28:43.130
Und 6 hoch 10, also selbst nach längeren arithmetischen Übungen kommt

28:43.130 --> 28:44.170
man bei einer Million raus.

28:45.170 --> 28:46.770
Warum soll es jetzt denn 12 sein?

28:46.950 --> 28:49.910
Und jetzt könnte man sagen, ja, weil die Millionen, dieser Rösterfasl,

28:49.970 --> 28:51.770
der die ganze Zeit auf einen Überlauf, vielleicht ja gar nicht

28:51.770 --> 28:52.710
irgendwo reinpasst.

28:52.710 --> 28:55.530
Und dann gab es vielleicht einen Überlauf bei einem Byte oder sowas.

28:55.630 --> 28:58.310
Und dann kommt am Ende halt Nummer 12 raus, weil das ist halt die

28:58.310 --> 28:59.830
Darstellung von einer Million in einem Byte.

29:00.410 --> 29:03.510
Leider nicht richtig, klingt zwar plausibel, ist aber nicht richtig.

29:03.690 --> 29:09.510
Und zwar, dieses hoch, Sie erinnern sich vielleicht noch, das ist der

29:09.510 --> 29:11.070
XOR -Operator.

29:11.830 --> 29:13.410
Exklusives Verodern der einzelnen Bits.

29:14.070 --> 29:16.270
Und deswegen schauen wir uns mal die Antwort an.

29:19.850 --> 29:21.190
Irgendwie ist das hier noch nicht ganz ausgereift.

29:25.950 --> 29:29.150
Ich bin ja froh, dass Sie noch aktiv sind in dem System.

29:32.010 --> 29:34.130
Jedes Mal, wenn eine neue Antwort von Ihnen kommt, ist es wieder weg.

29:34.270 --> 29:35.650
Ich versuche es aber mal mündlich zu erklären.

29:36.650 --> 29:42.370
Eine 10 ist eine Binärdarstellung 1 0 1 0 und eine 6 ist 0 1 1 0.

29:42.770 --> 29:44.010
Das ist erstmal so gegeben.

29:44.510 --> 29:51.270
Wenn Sie diese zwei Zeichenketten exklusiv verodern, das heißt also

29:51.270 --> 29:57.150
immer nur ein unterschiedlicher Bitwert an der jeweiligen Stelle nach

29:57.150 --> 30:01.370
1 gibt, dann kommt das raus, wir können das ja eigentlich mal gerade

30:01.370 --> 30:02.930
hier vorführen an dem System.

30:12.590 --> 30:18.850
Wenn wir also diese zwei Zeichenketten hier bitweise uns anschauen, wo

30:18.850 --> 30:22.370
es unterschiedliche Werte gibt, dann ist das nur den ersten beiden

30:22.370 --> 30:23.650
hochwertigsten Bit der Fall.

30:23.650 --> 30:27.570
Hier beides mal 0 ergibt 0 im X-Ohr, beides mal 1 ergibt auch 0, weil

30:27.570 --> 30:30.050
wir im X-Ohr sind, nicht in einem normalen Oder, sondern in einem

30:30.050 --> 30:30.850
exklusiven Oder.

30:31.750 --> 30:35.350
Und 0 und 1 ergibt 1 und 1 und 0 ergibt 1 und das zusammen ist halt

30:35.350 --> 30:36.070
12.

30:36.750 --> 30:40.830
Wenn man diese Zahl aus dem Binärsystem wieder umwandelt in eine

30:40.830 --> 30:41.670
Dezimalzahl.

30:42.010 --> 30:44.370
Das ist der Grund, warum das eben 12 ist.

30:46.730 --> 30:49.790
Gehen wir mal weiter zur

30:58.840 --> 30:59.560
nächsten Frage.

31:01.320 --> 31:03.020
Kann man mit...

31:03.020 --> 31:06.840
Ich sollte vielleicht fairerweise wieder umschalten.

31:07.140 --> 31:09.800
Kann man das machen, a kleiner b kleiner c?

31:11.740 --> 31:14.560
Und jetzt schauen wir mal an...

31:18.020 --> 31:19.800
Sie haben jetzt noch nicht geantwortet.

31:21.800 --> 31:26.260
Dann können diejenigen von Ihnen, die noch nicht ausgelockt sind, mal

31:26.260 --> 31:26.480
machen.

31:28.320 --> 31:30.000
Geht es in die richtige Richtung, was Sie sagen?

31:30.820 --> 31:34.560
Und zwar a kleiner b, kann man zwar als Vergleich durchführen.

31:34.620 --> 31:36.220
Das Ergebnis ist aber ein Wahrheitswert.

31:36.720 --> 31:37.400
Wahr oder falsch.

31:38.640 --> 31:41.320
Und egal, ob da jetzt wahr oder falsch rauskommt, aber ein Bullshit

31:41.320 --> 31:44.260
-Wert ist nicht vergleichbar mit einem c danach.

31:47.000 --> 31:48.380
Und deswegen geht es nicht.

31:48.500 --> 31:49.400
Also die Antwort ist nein.

31:51.240 --> 31:53.260
Und das haben Sie hier nicht geantwortet.

31:54.580 --> 31:55.940
Doch, das System.

32:05.220 --> 32:06.220
Soviel zum Thema Live.

32:06.820 --> 32:07.700
Hier steht immer noch null.

32:18.890 --> 32:21.350
Gut, das hat er jetzt irgendwie hier scheinbar nicht registriert, dass

32:21.350 --> 32:22.330
Sie hier geantwortet haben.

32:24.970 --> 32:27.130
Normalerweise würde es jetzt von Ja und Nein so zwei Balken

32:27.130 --> 32:27.610
einblenden.

32:27.750 --> 32:29.470
Irgendwie scheint das jetzt hier nicht anzukommen.

32:29.610 --> 32:34.970
Aber wie dem auch sei, die Erklärung ist so, wie ich es gesagt habe.

32:37.130 --> 32:41.670
Dass man das nicht partiell auswerten kann.

32:46.970 --> 32:49.730
Dann kommen wir zur dritten Frage.

32:52.870 --> 32:57.910
Kann man die Operatoren kleiner und größer verwenden, um String

32:57.910 --> 32:59.350
-Variablen zu vergleichen?

32:59.450 --> 33:00.970
So wie Sie das von Zahlen her können.

33:00.970 --> 33:02.510
Hier klappt es wieder.

33:02.830 --> 33:03.330
Es läuft.

33:03.630 --> 33:04.410
Wunderschön, klar.

33:06.210 --> 33:09.470
Jetzt mache ich mal das, was man als Bundeswahlleiter nicht darf.

33:09.710 --> 33:13.750
Nämlich schon Ergebnisse einblenden, bevor die Wahlkabinen geschlossen

33:13.750 --> 33:14.030
sind.

33:15.790 --> 33:21.050
Also 77% von Ihnen meinen, dass das wohl nicht geht.

33:21.250 --> 33:25.170
23% sind aber dafür, dass das geht.

33:25.790 --> 33:27.370
So schauen wir mal, was die Auflösung ist.

33:29.070 --> 33:30.030
Rappel, rappel, rappel.

33:32.270 --> 33:32.890
Okay, gut.

33:33.070 --> 33:33.930
Also es geht nicht.

33:35.190 --> 33:36.630
Also die Antwort ist, es geht nicht.

33:36.730 --> 33:40.050
Und zwar, weil es auf String-Operatoren nicht definiert ist in Java.

33:42.590 --> 33:46.810
Der Wert von einer Zeichenkette ist in dem Sinne nicht festgelegt.

33:47.030 --> 33:50.370
Und wenn der Wert nicht festgelegt ist, dann kann man es halt nicht

33:50.370 --> 33:50.850
machen.

33:51.770 --> 33:54.970
Sie sehen, kleine Überläufe gibt es auch hier in dem System.

33:57.170 --> 34:01.230
Wenn Sie sich wieder abmelden, bleibt natürlich Ihre Antwort erhalten.

34:01.390 --> 34:03.390
Das ist der Grund, warum es hier 209 gibt.

34:04.610 --> 34:06.470
Ich sehe schon, ich muss zur nächsten Frage hier.

34:08.050 --> 34:09.690
Das ist jetzt ein bisschen kniffliger.

34:11.450 --> 34:16.630
Was ist das Ergebnis von 1 durch 0 und 1,0 durch 0,0 in Java?

34:17.370 --> 34:20.830
Alle Leute, die von Ihnen nur ein bisschen mathematisches

34:20.830 --> 34:24.890
Fingerspitzengefühl am Tag legen, läuft ein Schauder über den Rücken,

34:25.050 --> 34:26.090
sowas zu lesen hier.

34:26.530 --> 34:28.830
1 durch 0, also normalerweise müssen Sie sich jetzt schütteln und

34:28.830 --> 34:30.670
sagen, um Gottes Willen, das darf ja nicht passieren.

34:31.490 --> 34:33.770
Aber was heißt das in der programmierenden Sprache Java?

34:37.630 --> 34:40.510
Also, belassen wir es mal an der Stelle.

34:40.830 --> 34:44.070
Also was ist das Ergebnis von 1 durch 0?

34:45.330 --> 34:46.510
Einrufen, ja.

34:47.370 --> 34:47.550
Bitte?

34:49.290 --> 34:50.010
Ganz genau.

34:50.010 --> 34:54.810
Der interessante Art und Weise ist jetzt, wenn ich Integer 1 durch 0

34:54.810 --> 35:00.250
teile und Flowzahlen, also Fließkommazahlen 1,0 durch 0,0, kommt

35:00.250 --> 35:02.810
interessanterweise in Java was unterschiedliches raus.

35:03.690 --> 35:06.350
Das ist also in dem Sinne nicht geht, ist klar.

35:06.510 --> 35:09.030
Mathematisch ist das vielleicht Unendlichkeit, wenn man so will.

35:09.910 --> 35:14.030
Also bei 1 durch 0 im Integer-Bereich, also dem ersten von den beiden

35:14.030 --> 35:19.470
hier, kommt tatsächlich ein Division-by-Zero-Exception.

35:19.890 --> 35:21.370
Die wird geworfen und das geht nicht.

35:22.930 --> 35:26.850
Bei 1,0 durch 0,0 könnte man erwarten, dass es dasselbe passiert.

35:26.890 --> 35:28.170
Das ist aber interessanterweise nicht der Fall.

35:28.350 --> 35:29.550
Und zwar, was kommt hier?

35:30.030 --> 35:34.890
Hier kommt Infinity als Wert raus, also Endlichkeit, was mathematisch

35:34.890 --> 35:36.610
gesehen, kann man sagen, einen gewissen Sinn macht.

35:37.450 --> 35:40.690
Jetzt ist die Frage, warum ist das in unterschiedlichen Java geregelt?

35:40.690 --> 35:44.550
Also warum ist bei dem Integer, wird brav Division-by-Zero gemeldet,

35:44.630 --> 35:48.670
wohingegen, wenn man quasi dasselbe macht, nur in der Gleitkommazahl,

35:48.770 --> 35:50.150
wird der Wert unendlich reingeschrieben.

35:50.610 --> 35:52.470
Die eine Antwort ist ziemlich banal.

35:52.910 --> 35:57.490
Das steht im IEEE-Gleitkommastandard so drin, dass da eben Infinity

35:57.490 --> 35:58.510
reingeschrieben werden muss.

35:59.010 --> 36:00.970
Und wenn man die Standard implementiert, hat man natürlich keine Wahl.

36:01.590 --> 36:05.490
Deshalb ist natürlich keine vielleicht geistig befriedigende Antwort.

36:06.010 --> 36:08.070
Man fragt sich ja, warum haben die das in den gleichen Standards so

36:08.070 --> 36:08.570
reingeschrieben.

36:10.910 --> 36:15.870
Und letzten Endes ist die Überlegung grob die, wenn ich Gleitkomma

36:15.870 --> 36:19.950
-Arithmetik betreibe, habe ich, wie ich ja sagte, immer das Problem,

36:20.090 --> 36:22.430
dass die Genauigkeit ja unter Umständen nicht hundertprozentig ist,

36:22.510 --> 36:24.190
und dass ich nur nur Approximativ rechne.

36:24.930 --> 36:28.910
Und insofern ist also, wenn ich eine Zahl durch etwas sehr, sehr

36:28.910 --> 36:31.990
kleines teile, komme ich immer näher an die Unendlichkeit dran.

36:32.090 --> 36:36.370
Und vielleicht ist das eben das, was hier im Prinzip auch passiert

36:36.370 --> 36:39.270
ist, dass man eigentlich gar nicht die Null im Teiler haben wollte,

36:39.510 --> 36:41.910
sondern halt nur einen sehr, sehr kleinen Wert hatte, der aber nicht

36:41.910 --> 36:42.850
exakt dargestellt wurde.

36:42.930 --> 36:45.370
Und deswegen ist halt dann mathematisch gesehen Unendlichkeit hier die

36:45.370 --> 36:45.650
Antwort.

36:46.410 --> 36:49.530
Wohingegen man bei 1 durch 0 im Integer-Bereich, wo man keine

36:49.530 --> 36:51.890
Rundungsfehler hat, einfach sagt, das ist ein Fehler.

36:51.990 --> 36:54.070
Und wenn sowas auftaucht, dann hätte der Programmierer das gefälligst

36:54.070 --> 36:55.010
besser abfangen sollen.

36:56.270 --> 37:03.330
Jetzt kann man darüber streiten und sagen, naja, ist das so schlau,

37:03.390 --> 37:06.990
sollte nicht vielleicht immer eine Fehlermeldung geworfen werden,

37:07.030 --> 37:09.630
damit der Programmierer weiß, hier ist jetzt eine Situation passiert,

37:09.710 --> 37:11.230
die eigentlich wahrscheinlich so nicht geplant war.

37:11.930 --> 37:15.130
Aber gut, der Standard hat es nochmal so festgelegt und deswegen ist

37:15.130 --> 37:15.830
es jetzt so geregelt.

37:15.930 --> 37:18.830
Das Erste ergibt also Division by Zero als Exception.

37:19.250 --> 37:20.710
Der Programmfluss wird unterbrochen.

37:21.170 --> 37:23.730
Bei dem anderen wird überhaupt kein Programmfluss durchbrochen,

37:23.810 --> 37:25.750
sondern einfach nur Infinity in das Ergebnis reingeschrieben.

37:26.010 --> 37:27.510
Damit weiterrechnen können Sie aber auch nicht.

37:29.430 --> 37:31.010
So, gehen wir mal in die nächste.

37:38.190 --> 37:40.810
Dann machen wir die Vorlesung jetzt weiter.

37:42.950 --> 37:47.670
Ich hatte schon eben auf der Tonspur mehrfach von Variablen

37:47.670 --> 37:48.410
gesprochen.

37:50.790 --> 37:53.370
Variable ist in dem Sinne eine Instanz einer Variable.

37:53.450 --> 37:56.230
Und Instanz können Sie jetzt erstmal genauso sehen, wie wir das in der

37:56.230 --> 37:59.230
Vorlesung vorher zwischen Klassen und Objekten gesehen haben.

37:59.410 --> 38:04.770
Wir haben Klassen festgelegt, zum Beispiel Vektor 2D, für allgemein

38:04.770 --> 38:07.090
alle möglichen zweidimensionalen Vektoren.

38:07.550 --> 38:10.510
Und dann hatten wir Instanzen davon, das waren die Objekte.

38:11.090 --> 38:14.890
Und wir konnten auch mehrere 2D-Vektoren haben, die alle aber nach

38:14.890 --> 38:19.110
diesem selben Bauplan, der in der Klasse festgelegt war, erzeugt

38:19.110 --> 38:19.330
werden.

38:20.190 --> 38:22.810
Und im Prinzip haben wir eine ähnliche Beziehung auch zwischen Typen

38:22.810 --> 38:23.510
und Variablen.

38:23.510 --> 38:25.650
Ein Typ legt eben den Wertebereich fest.

38:25.750 --> 38:27.510
Wir haben das eben für verschiedene Dinge diskutiert.

38:28.090 --> 38:30.590
Für Ganzzahlen, für Gleitkommazahlen, für Zeichenketten und so weiter.

38:32.150 --> 38:34.630
Und jetzt ist eine Variable letzten Endes die Instanz dafür.

38:34.730 --> 38:37.910
Also wenn man so will, der Platzhalter, wo dann ein konkreter Wert

38:37.910 --> 38:38.790
drinstehen kann.

38:41.250 --> 38:47.490
In Java ist es notwendig, dass man den Typ einer Variable deklariert.

38:47.630 --> 38:50.570
Also das überlegt sich der Übersetzer oder das Java-System nicht von

38:50.570 --> 38:50.970
alleine.

38:51.770 --> 38:53.030
Welcher Typ könnte das sein?

38:53.090 --> 38:54.670
Es gibt andere Programmiersprachen, da ist es so.

38:54.750 --> 38:56.230
Da braucht man sich selber den Typ hinschreiben.

38:56.890 --> 38:58.290
Aber in Java muss man das halt immer machen.

38:58.390 --> 38:59.530
Und das schreibt man einfach immer davor.

38:59.750 --> 39:00.770
Das ist ein relativ einfaches Schema.

39:01.310 --> 39:03.130
Erst kommt der Typ und dann der Name der Variable.

39:03.510 --> 39:06.050
Oder Sie können auch mehrere Variablen danach deklarieren.

39:07.050 --> 39:10.010
Also zum Beispiel wird hier eine Variable A vom Typ Gleitkommazahl

39:10.010 --> 39:14.730
deklariert oder die Variable XYZ als Ganzzahlen.

39:16.690 --> 39:20.150
Wenn ich jetzt so eine Variable habe, kann die halt verschiedene Werte

39:20.150 --> 39:20.590
einnehmen.

39:21.970 --> 39:24.310
Und das passiert durch diesen Zuweisungsoperator.

39:25.310 --> 39:28.870
Sie haben sich erinnert, Gleichheitsoperator war in Java gleichgleich.

39:29.750 --> 39:32.990
Damit hat man eine Operation, die zwei Entitäten auf Gleichheit

39:32.990 --> 39:34.650
überprüft und einen Boolean-Wert zurückliefert.

39:35.730 --> 39:38.750
Der Gleichoperator, die Zuweisung, das einfache Gleich nutzen wir

39:38.750 --> 39:39.010
hier.

39:39.570 --> 39:41.450
Aber zum Beispiel hier auf 2,5 geschrieben.

39:41.450 --> 39:44.770
Man kann aber auch das alles zusammenfassen, die Initialisierung und

39:44.770 --> 39:45.630
die Deklaration.

39:46.370 --> 39:50.250
Und dann hat man hier hingeschrieben zum Beispiel Float A.

39:50.350 --> 39:54.070
Das heißt A hat den Typ Float und es wird initialisiert mit dem Wert 2

39:54.070 --> 39:54.630
,5.

39:57.090 --> 39:59.950
Und die Variablen, die sind uns schon aufgetaucht, als wir damals

39:59.950 --> 40:01.870
diese Klassendeklaration hatten.

40:02.270 --> 40:04.690
Und da zum Beispiel schon die Koordinaten angegeben hatten mit X und

40:04.690 --> 40:04.910
Y.

40:07.750 --> 40:11.890
Der Gag ist jetzt, dass im Laufe des Programms, wenn also das Programm

40:11.890 --> 40:15.250
abläuft, Rechnungen passieren, Variablen ihre Werte ändern.

40:16.430 --> 40:20.330
Und das nutzt man in der Regel mit dem Zuweisungsoperator, wo dann z

40:20.330 --> 40:20.330
.B.

40:20.650 --> 40:23.170
Zwischenergebnisse oder Ergebnisse in Variablen gespeichert werden.

40:24.290 --> 40:30.730
Und hier sieht man das zum Beispiel, X gleich Y ändert den Wert der

40:30.730 --> 40:33.790
Variablen X und setzt ihn auf den Wert der Variablen Y.

40:34.270 --> 40:37.290
Danach kann natürlich Y wieder andere Werte annehmen, das kriegt dann

40:37.290 --> 40:38.010
X wieder nicht mit.

40:40.070 --> 40:43.350
Dann gibt es hier, und da sieht man eben diese Zuweisung, das ist was,

40:43.610 --> 40:45.790
was jetzt mathematisch einem vielleicht irgendwie etwas irritiert.

40:45.830 --> 40:47.810
Jetzt sagt man, X ist gleich X plus 1.

40:47.890 --> 40:50.410
Der Mathematiker würde sofort aufheulen und sagen, hallo, was war denn

40:50.410 --> 40:50.650
das?

40:51.070 --> 40:52.870
Die Gleichung ist ja nie wahr.

40:54.370 --> 40:56.370
Die einfache Einsicht ist, es ist aber keine Gleichung, es ist eine

40:56.370 --> 40:56.870
Zuweisung.

40:56.870 --> 41:02.370
Der neue Wert von X ist der alte Wert von X, aber um 1 inkrementiert,

41:02.450 --> 41:03.030
also plus 1.

41:07.390 --> 41:10.350
Hier sehen Sie, wenn ich jetzt zum Beispiel X und Y verschiedene Werte

41:10.350 --> 41:15.650
zuweise, zum Beispiel 10 und 6, und dann X gleich X plus 1, dann

41:15.650 --> 41:17.410
bekommt zum Beispiel X den Wert 11.

41:17.950 --> 41:21.790
Wenn ich X gleich Y sage, wird eben dieser Wert aus Y, die 6,

41:21.950 --> 41:22.790
übertragen ans X.

41:22.790 --> 41:26.690
Und wenn ich jetzt zum Beispiel sage, Y ist 2 mal X plus 1, dann

41:26.690 --> 41:29.270
ergibt sich hier eben 13 aus 2 mal 6 plus 1.

41:31.390 --> 41:34.250
Die Story ist relativ simpel, es gibt eigentlich nur zwei Botschaften.

41:34.330 --> 41:37.110
Erstens mal unterscheiden Sie zwischen einem Zuweisungsapparator, ein

41:37.110 --> 41:39.970
einfaches Gleich, und einem Vergleichsapparator, zwei

41:39.970 --> 41:40.810
Gleichheitszeichen.

41:41.730 --> 41:42.870
Das ist halt nicht dasselbe.

41:43.370 --> 41:48.030
Dann das andere ist, wichtig ist hier, dieses Gleich hier dürfen Sie

41:48.030 --> 41:52.310
eben nicht mathematisch lesen, dass jetzt ich einen Wert für X finden

41:52.310 --> 41:54.810
muss, wie die linke und rechte Seite ausgeglichen ist, wie Sie es in

41:54.810 --> 41:56.070
einer mathematischen Gleichung hätten.

41:57.070 --> 41:59.390
Klar, das geht halt nicht, wenn X ist gleich X plus 1 hier steht,

42:00.170 --> 42:03.970
sondern es ist halt eine Zuweisung, wo man sagt, der neue Wert von X

42:03.970 --> 42:06.790
ist der alte Wert plus 1.

42:07.430 --> 42:12.210
So liest sich eben diese Zeile, was eben keine Gleichung ist.

42:14.130 --> 42:18.130
So, genau, das steht auch nochmal hier zum Nachlesen.

42:21.490 --> 42:26.450
Wenn Sie jetzt ein Objekt haben, und Sie erinnern sich, es gibt

42:26.450 --> 42:29.810
Attribute von den Klassen, die dann auch das Objekt als Variable hat,

42:30.270 --> 42:33.250
und jetzt möchte man die setzen, dann geschieht das über diesen

42:33.250 --> 42:34.710
Punktoperator.

42:36.210 --> 42:40.390
Wenn wir diese Klasse, die wir in der ersten Vorlesung schon hatten,

42:40.390 --> 42:47.010
Vektor 2D mit X- und Y-Koordinaten, die Werte setzen möchten, dann

42:47.010 --> 42:52.650
müssen wir P.X schreiben, damit können wir die Variable X im Vektor P

42:52.650 --> 42:56.370
adressieren oder P.Y im Y-Koordinaten.

42:59.490 --> 43:02.550
Wenn man sich das grafisch so vorstellt, hier haben Sie also Ihr

43:02.550 --> 43:07.430
Objekt P vom Typ Vektor 2D und das hat selber wieder eine X- und eine

43:07.430 --> 43:09.690
Y -Variable und die haben diese Werte hier.

43:12.780 --> 43:15.360
Und hier unten können Sie es auch mal auf Gleitkommazahlen setzen,

43:15.520 --> 43:17.720
weil nämlich das auch als Gleitkommazahlen definiert war.

43:22.720 --> 43:26.540
Technisch ist eine Variable eigentlich ein Name für einen

43:26.540 --> 43:27.260
Speicherplatz.

43:28.760 --> 43:33.620
Sie haben einen Variable-Namen, Sie haben einen Wert und Sie haben

43:33.620 --> 43:37.800
einen Typ davon, das beschreibt, was für Werte können überhaupt in

43:37.800 --> 43:39.160
dieser Variable gespeichert werden.

43:41.260 --> 43:44.240
Und Sie können sich also dieses Triple hier vorstellen, X als Variable

43:44.240 --> 43:47.820
-Name, 0 als der Wert quasi, Gefäßinhalt, so in Anführungsstrichen,

43:48.420 --> 43:51.620
und Int, das ist, wenn man so will, die Form des Gefäßes oder eben der

43:51.620 --> 43:51.900
Typ.

43:53.120 --> 43:57.880
Und das ist alles zusammengekapselt, ergibt das eben eine Variable.

43:58.280 --> 44:01.480
Und wenn Sie jetzt eine Zuweisung machen, wie zum Beispiel hier X

44:01.480 --> 44:06.020
gleich 4295, dann wird dieser Wert dem X zugewiesen.

44:06.200 --> 44:09.280
Der Rest bleibt natürlich, der Name von X bleibt bestehen, der Typ

44:09.280 --> 44:10.240
bleibt auch bestehen.

44:12.960 --> 44:16.620
Bis auf ein paar Übeltricksereien ist es schon so, dass letzten Endes

44:16.620 --> 44:20.140
der Typ einer Variable für die gesamte Lebenszeit der Variable auch

44:20.140 --> 44:20.660
festgelegt ist.

44:20.700 --> 44:22.940
Wenn Sie das einmal deklarieren, das X als Integer, dann bleibt es

44:22.940 --> 44:23.500
auch ein Integer.

44:26.020 --> 44:31.180
So, der Hauptspeicher in Ihrem Computer besteht erst einmal aus einer

44:31.180 --> 44:32.720
Reihung von Speicherzellen.

44:37.550 --> 44:42.230
Und diese Speicherzellen hintereinander sind in Wirklichkeit in Bytes

44:42.230 --> 44:42.410
aufgeteilt.

44:43.050 --> 44:47.090
Das brauchen Sie aber jetzt in dem Augenblick hier... Entschuldigung,

44:47.310 --> 44:48.350
jetzt ist alle wach...

44:49.730 --> 44:52.050
Das brauchst Du jetzt aber nicht weiter irritieren, dass wir jetzt so

44:52.050 --> 44:55.530
tun, als ob jede Variable immer in einen Speicherplatz reinpasst.

44:55.610 --> 44:57.910
Das ist technisch gesehen in Wirklichkeit nicht so.

44:58.330 --> 45:01.810
Ein Integer, hatte ich Ihnen so nebenbei erwähnt, das hat 4 Bytes

45:01.810 --> 45:06.250
Länge, ein Long hat 8 Bytes Länge, ein Short hat nur 2 Bytes Länge,

45:06.890 --> 45:08.410
ein Character hat nur 1 Byte Länge.

45:08.670 --> 45:10.270
Das braucht Sie jetzt erstmal nicht interessieren, diese

45:10.270 --> 45:11.330
unterschiedlichen Byte Längen.

45:11.430 --> 45:15.270
Stellen Sie sich einfach vor, ich habe im Hauptspeicher Speicherplätze

45:15.930 --> 45:18.930
und jeder von denen kann eine Variable speichern.

45:19.810 --> 45:22.550
Klammern für die Technikfreaks, wenn eine Variable halt mehr als einen

45:22.550 --> 45:24.510
Byte braucht, dann nimmt sie halt mehrere hintereinander, die da

45:24.510 --> 45:26.110
liegen und sagen, das ist jetzt meine Variable.

45:26.570 --> 45:29.590
Darum brauchen wir uns aber als Java-Programmierer nicht kümmern.

45:30.670 --> 45:34.410
Wir können erstmal so tun, als ob der Speicher eine Folge von

45:34.410 --> 45:38.330
durchnummerierten Speicherzellen ist und jeder von denen kann eine

45:38.330 --> 45:39.450
Variable beinhalten.

45:43.400 --> 45:45.500
Warum habe ich das jetzt so aufwendig hier hingemalt?

45:45.500 --> 45:50.000
Um Ihnen zu visualisieren, wie das jetzt aussieht.

45:50.600 --> 45:55.060
Zuweisung x und y, 2,0 oder 3,5, das sieht dann so aus.

45:55.880 --> 46:03.640
Und jetzt kommt es, wenn ich jetzt ein Objekt habe vom Typ Vector2D,

46:03.820 --> 46:07.020
also ein Objekt, und das nenne ich pos.

46:09.740 --> 46:15.700
Dann ist das pos selber nichts anderes als ein Verweis auf den Teil im

46:15.700 --> 46:20.580
Speicher, wo die Attribute, die Variablen, von meinem Objekt

46:20.580 --> 46:21.820
tatsächlich gespeichert sind.

46:21.980 --> 46:26.360
Das heißt, wenn zum Beispiel ab der Speicherzelle mit der Nummer 17

46:26.360 --> 46:32.300
die Variablen im Speicher liegen, von meinem Objekt pos, dann hat pos

46:32.300 --> 46:35.260
selber als Variable den Wert 17.

46:35.260 --> 46:37.140
Mit dem können Sie aber nichts anfangen.

46:37.520 --> 46:39.520
Das ist eine Speichernummer.

46:40.380 --> 46:43.480
Und diese Speichernummer wird nur intern vom Java-System genutzt, um

46:43.480 --> 46:46.400
dann da den Speicher zu finden, wo die Werte tatsächlich liegen.

46:47.060 --> 46:51.060
Sie können auch in Java nicht mit diesem Wert rumrechnen oder so.

46:51.800 --> 46:54.900
Wieder für unseren charakterhaften C-Programmierer, in C könnte man

46:54.900 --> 46:55.380
das natürlich.

46:56.740 --> 46:58.960
Aber das ist natürlich sehr fehlerträchtig, wenn man mit

46:58.960 --> 47:00.100
Speicheradressen rumrechnet.

47:01.280 --> 47:04.560
So, jetzt schauen wir uns mal die folgende Situation an.

47:06.460 --> 47:08.480
Ich mache new.

47:08.660 --> 47:10.940
Was das tut, erzähle ich Ihnen in der nächsten Vorlesung.

47:11.540 --> 47:16.200
Also ich besorge mir eine Instanz von einem Vektor und diese Instanz

47:16.200 --> 47:17.840
wird in p gespeichert.

47:18.100 --> 47:19.340
Das passiert letztendlich durch new.

47:19.440 --> 47:23.820
Ich bekomme ein Objekt von der Klasse, vom Typ Vektor, mit diesen

47:23.820 --> 47:27.320
Werten initialisiert und jetzt bekomme ich auch noch eine Variable q.

47:27.840 --> 47:31.620
Das ist auch ein Vektor, der auch wieder initialisiert wurde mit den

47:31.620 --> 47:34.540
Werten und das Objekt, was mit new erzeugt wird, das wird hier

47:34.540 --> 47:35.080
gespeichert.

47:35.860 --> 47:39.320
So, dann habe ich also p, q und r habe ich auch.

47:39.440 --> 47:43.840
r setze ich hier auf den Wert von p und hier habe ich dann den

47:43.840 --> 47:44.280
Speicher.

47:44.960 --> 47:48.120
Und p zeigt zum Beispiel auf die Nummer 17 und hat hier die Werte 2,0

47:48.120 --> 47:49.420
und 3,5.

47:49.940 --> 47:55.920
q zeigt auf den Wert 20 und da ist tatsächlich, wie ich es ja auch

47:55.920 --> 48:00.980
festgelegt habe, ein Vektor mit der Richtung 1,2 und 9,4 gespeichert.

48:03.220 --> 48:11.060
Und durch r gleich p passiert jetzt eine Zuweisung, dass die Variable

48:11.060 --> 48:13.400
r den Wert der Variable p bekommt.

48:13.560 --> 48:17.600
p hat den Wert 17, das verweist nämlich genau auf dieses Objekt hier

48:17.600 --> 48:19.880
im Speicher und r bekommt jetzt auch diesen Wert.

48:20.480 --> 48:24.220
Das ist das Einzige, was Sie mit Speicheradressen in Java machen

48:24.220 --> 48:26.000
können, Sie können Zuweisungen machen.

48:27.140 --> 48:30.540
In C, wie gesagt, können Sie auch addieren, multiplizieren, zerhexeln,

48:30.900 --> 48:33.060
kopieren und sonst was alles, aber in Java können Sie es nur

48:33.060 --> 48:34.040
Zuweisungen machen.

48:36.380 --> 48:41.420
So, wenn ich jetzt die Zuweisung mache, p ist gleich q, was passiert

48:41.420 --> 48:41.600
dann?

48:41.640 --> 48:46.860
Die 17 wird überschrieben von dem Wert von q, das ist die 20, die

48:46.860 --> 48:53.140
steht jetzt hier und damit quasi zeigt p jetzt nicht mehr auf die 17,

48:53.300 --> 48:55.920
sondern eben auf die 20, auf dieses Objekt.

48:57.500 --> 49:01.560
Jetzt könnte es ja sein, dass keiner hier mehr auf das Objekt zeigt,

49:01.660 --> 49:02.880
das ist momentan noch nicht der Fall.

49:03.040 --> 49:07.580
r zeigt ja immer noch auf die 17 hier, aber angenommen wir hätten

49:07.580 --> 49:10.480
diese Geschichte mit dem r nicht gemacht, sondern würden einfach nur

49:10.480 --> 49:15.320
hier p gleich q schreiben, dann wäre im Prinzip die Information, wo

49:15.320 --> 49:18.280
liegt eigentlich dieses Objekt hier im Speicher, was hier mal erzeugt

49:18.280 --> 49:20.440
wurde, verloren gegangen sein, weil sich keiner mehr merkt.

49:21.820 --> 49:24.820
Und das heißt, ich habe hier im Speicher ein Objekt, was offenbar

49:24.820 --> 49:27.180
keiner mehr braucht, weil er kann es ja überhaupt nicht mehr

49:27.180 --> 49:27.640
ansprechen.

49:28.800 --> 49:32.360
Und in Java ist es so, es gibt einen Hintergrundprozess, das ist der

49:32.360 --> 49:35.440
sogenannte Speicherbereiniger auf Deutsch oder auf Englisch, Garbage

49:35.440 --> 49:39.140
Collector, der geht nach einem gewissen Algorithmus durch und sucht

49:39.140 --> 49:42.040
immer die Objekte, die nicht mehr referenziert werden, wo keiner mehr

49:42.040 --> 49:45.340
drauf zeigt und gibt diesen Speicher auch wieder frei, weil der

49:45.340 --> 49:47.060
braucht gar nicht mehr belegt werden, weil es kann eh nicht mehr

49:47.060 --> 49:49.080
dereferenziert werden, wie man sagt.

49:51.280 --> 49:54.920
An der Stelle jetzt nochmal eine grafische Visualisierung von unserer

49:54.920 --> 49:56.420
Situation von eben.

49:57.180 --> 50:02.140
Ich habe meine Objekte, die hier zum Beispiel an den Adressen, die wir

50:02.140 --> 50:04.980
eben hatten, 17 und 18 liegen und 20 und 21.

50:06.100 --> 50:08.220
Ich habe p, das zeigt auf die 17.

50:08.620 --> 50:10.060
Ich habe q, das zeigt auf die 20.

50:10.200 --> 50:13.580
Das waren Zuweisungen, die durch diesen new Operator passiert waren.

50:15.220 --> 50:22.000
Und ich habe dann diese Zuweisung r gleich p und dann zeigt eben r

50:22.000 --> 50:23.260
auch auf die 17.

50:23.380 --> 50:25.820
Es wird also kein neues Objekt erzeugt.

50:25.920 --> 50:28.200
Ich habe nach wie vor die beiden Objekte, die ich mit new erzeugt

50:28.200 --> 50:28.340
habe.

50:28.340 --> 50:32.140
Und in erster grober Näherung, außer mit new, bekommen Sie auch keine

50:32.140 --> 50:32.780
neuen Objekte.

50:33.000 --> 50:34.920
Stimmt nicht ganz, aber für unser Beispiel erstmal.

50:36.020 --> 50:39.340
Das heißt, wenn Sie so eine einfache Zuweisung machen, r gleich p,

50:39.480 --> 50:40.880
erzeugen Sie kein neues Objekt.

50:41.740 --> 50:46.960
Sie legen nur die sogenannte Referenz jetzt fest auf dieses Objekt.

50:47.100 --> 50:49.580
Das heißt, Sie sehen, es kann also durchaus auch sein, dass zwei

50:49.580 --> 50:53.080
Objektreferenzen, in dem Fall jetzt p und r, die beiden Variablen, auf

50:53.080 --> 50:57.380
dasselbe Objekt im Speicher zeigen, was nämlich auch nur einmal hier

50:57.380 --> 50:58.040
abgelegt wurde.

51:00.060 --> 51:02.640
So, und jetzt machen Sie die Zuweisung p gleich q.

51:03.060 --> 51:03.940
Und was passiert jetzt?

51:04.060 --> 51:08.080
Naja, jetzt wird hier für diesen Wert p der Wert von q eingetragen.

51:08.280 --> 51:09.600
Das ist eine erstmal ganz normale Variable.

51:10.320 --> 51:12.100
Und dann zeigt das eben auch hier runter.

51:12.360 --> 51:15.560
Man sagt also, die Referenz wurde umgebogen.

51:16.000 --> 51:18.420
So als ob Sie jetzt als Maschinenbauer hier so ein Stück Stahl dengeln

51:18.420 --> 51:20.120
und diesen Zeiger da runterlegen.

51:24.200 --> 51:28.000
Und wenn ich jetzt eine Zuweisung mache auf eine Variable, dann wird

51:28.000 --> 51:33.920
im Fachjargon sagt man dereferenziert, also p.x ist gleich 7,5.

51:34.020 --> 51:37.460
Dann wird jetzt nichts an den Referenzen geändert, sondern tatsächlich

51:37.460 --> 51:39.780
an den Werten der Attribute der Variable.

51:39.940 --> 51:44.120
Und mit p.x würde man also dann hier diesen Wert x ändern.

51:48.490 --> 51:55.210
So, diese Situation, dass verschiedene Objektreferenzen auf dasselbe

51:55.210 --> 51:59.530
Objekt zeigen können, nennt man im Fachjargon auch Aliasing.

52:02.670 --> 52:06.070
Man sagt dann auch manchmal so, ja, das ist ja nur ein Alias dafür.

52:06.270 --> 52:08.350
Also das ist quasi ein zweiter Name für dasselbe Ding.

52:10.510 --> 52:14.350
Alias ist ja auch im Prinzip ein zweiter Name für dieselbe Person, ein

52:14.350 --> 52:14.810
Alias.

52:15.170 --> 52:17.710
Und genauso ist es eben hier, wenn ich zwei Objektreferenzen habe,

52:17.810 --> 52:20.710
dann sagt man, also der eine ist nur ein Alias für dieses Objekt, aber

52:20.710 --> 52:22.970
letzten Endes ist es dasselbe Objekt, was dahinter steckt.

52:26.020 --> 52:28.980
Jetzt gibt es noch eine ganz wichtige Konstante.

52:29.880 --> 52:35.600
Und zwar, wie ich sagte, bevor Sie kein new aufgerufen haben, wird

52:35.600 --> 52:36.960
auch kein Objekt erzeugt.

52:37.060 --> 52:40.920
Das heißt, wenn Sie nur die Variable eines Objekts, also den

52:40.920 --> 52:43.900
Objektnamen alleine deklarieren, ohne einen new Aufruf, haben Sie

52:43.900 --> 52:44.800
erstmal noch kein Objekt.

52:44.800 --> 52:46.220
Die Frage, wo zeigt Ihnen das jetzt hin?

52:47.320 --> 52:49.000
In C ist die Antwort auf irgendwas.

52:50.200 --> 52:52.420
In Java ist es ein bisschen definierter, die Welt.

52:52.960 --> 52:55.440
Da wird der Wert Null eingetragen.

52:55.840 --> 52:59.440
Und Null, also wirklich N-U-L-L, das ist eine Konstante in Java.

53:00.000 --> 53:04.520
Das ist quasi die Referenz auf die nullte Speicheradresse.

53:04.840 --> 53:07.220
Jetzt fangen Sie aber ja nicht an, an der nullten Speicheradresse

53:07.220 --> 53:09.740
rumzuvorwerken, die gehört Ihnen gar nicht, da kümmert sich das

53:09.740 --> 53:10.700
Betriebssystem in der Regel.

53:11.960 --> 53:17.560
Das heißt also, sofern Sie es wirklich schaffen, eine Objektreferenz

53:17.560 --> 53:20.520
mit Null zu dereferenzieren, wird Ihr Programm abstürzen, bzw.

53:20.620 --> 53:22.520
mit einem Exception aufhören.

53:24.380 --> 53:28.140
Das Prinzip hier nur steht dafür, dass eben noch kein Objekt

53:28.140 --> 53:30.540
zugewiesen wurde und Sie müssen mit new noch eins zuweisen.

53:30.660 --> 53:36.700
Also wenn ich jetzt zum Beispiel Vector2DP deklariere oder noch gleich

53:36.700 --> 53:40.020
Null dahinter schreibe, das müsste ich gar nicht, dann steht hier

53:40.020 --> 53:42.060
erstmal nur der Wert Null, das heißt es wurde noch kein Objekt

53:42.060 --> 53:42.580
erzeugt.

53:43.180 --> 53:47.580
Erst dann, wenn Sie mal bei Gelegenheit new machen, dann wird jetzt

53:47.580 --> 53:50.440
hier tatsächlich ein Objekt erzeugt und dann hier die Adresse

53:50.440 --> 53:50.660
eingetragen.

53:51.320 --> 53:52.800
Und p wirkt dann eben als Referenz.

53:56.920 --> 53:59.080
Dann noch ein bisschen was Besonderes.

54:00.080 --> 54:05.420
Man kann vor variablen Deklarationen das Wort final schreiben.

54:05.420 --> 54:07.400
Also erstmal genau wie eben.

54:08.200 --> 54:11.100
Man kann einen Typ angeben und einen Variablen Namen.

54:11.880 --> 54:14.560
Jetzt kann ich final da vorschreiben, das heißt es handelt sich um

54:14.560 --> 54:17.400
eine Konstante, ein Wert, der nicht mehr geändert werden soll.

54:19.940 --> 54:22.240
Und weise dem jetzt hier einen Wert zu.

54:26.980 --> 54:28.320
Was habe ich gemacht?

54:28.440 --> 54:33.440
Jetzt habe ich für bestimmte mathematische Werte einen Variablen Namen

54:33.440 --> 54:34.620
vergeben, der aber fix ist.

54:34.620 --> 54:36.280
Also nennt man das eine Konstante.

54:37.120 --> 54:38.020
Warum mache ich das?

54:38.280 --> 54:40.260
Ich könnte natürlich genauso mit der Zahl rechnen, das ist aber das

54:40.260 --> 54:42.640
gleiche wie eben bei den Enum-Typen.

54:43.260 --> 54:46.660
Je mehr Sie hier mit Begriffen arbeiten, die eine bestimmte Bedeutung

54:46.660 --> 54:50.120
haben, eine bestimmte Semantik, desto leichter wird nachher das

54:50.120 --> 54:50.940
Programm zu verstehen.

54:51.280 --> 54:59.000
Wenn Sie hier 3,1515 sehen, dann wissen Sie, das könnte p sein, das

54:59.000 --> 55:00.880
könnte vielleicht auch nicht p sein, das könnte auch was anderes sein.

55:00.880 --> 55:04.460
Wenn ich das p nenne, weiß ich, hier wollte der Entwickler den Wert

55:04.460 --> 55:05.620
von p eintragen.

55:05.700 --> 55:07.320
Er hat das mit einer gewissen Genauigkeit getan.

55:07.440 --> 55:10.280
Und wenn ich eine größere Genauigkeit habe, dann muss ich bei der

55:10.280 --> 55:13.860
Konstantendeklaration, also nur einmal im Programm, das ändern,

55:14.500 --> 55:17.160
genauer hinschreiben, dann wird es bei allen Verwendungen auch

55:17.160 --> 55:17.920
automatisch genutzt.

55:19.220 --> 55:21.500
Und das ist halt wesentlich bequemer, als wenn ich immer nur direkt

55:21.500 --> 55:22.860
Zahlen hart reinkodiere.

55:23.560 --> 55:25.860
Also Sie sollten sich mal so als Faustregel beim Programmieren

55:25.860 --> 55:28.480
angewöhnen, wenn Sie eine andere Zahl als 0 oder 1 in Ihren

55:28.480 --> 55:31.180
Programmtext reinschreiben, dann haben Sie irgendwas falsch gemacht,

55:31.240 --> 55:32.560
dann sollten Sie eine Konstante deklarieren.

55:33.580 --> 55:36.900
Weil 0 und 1, okay, das kann man sich noch vorstellen meistens, was

55:36.900 --> 55:39.540
das bedeutet, aber alle anderen Zahlen haben irgendeine Bedeutung, die

55:39.540 --> 55:42.160
durch die Zahl selber nicht klar wird, und das sollten Sie, wenn Sie

55:42.160 --> 55:44.840
explizit eine Zahl reintippen, also wenn ich einen Programmtext sehe,

55:44.920 --> 55:45.780
gleich 17.

55:46.160 --> 55:47.180
Da hat man schon die Krise bekommen.

55:47.260 --> 55:50.020
Die 17 hat irgendeine Bedeutung aus der Anwendungsdomäne, das sollten

55:50.020 --> 55:51.600
Sie vorher als Konstante deklarieren.

55:51.960 --> 55:53.620
Also kein Mensch weiß nachher, was die 17 sollte.

55:57.870 --> 56:01.210
Und also wie gesagt, das hier ist auch wieder eine Möglichkeit, Ihr

56:01.210 --> 56:04.290
Programm ausdrucksmächtiger zu machen, indem Sie Konstanten

56:04.290 --> 56:04.850
deklarieren.

56:07.630 --> 56:09.490
Fassen wir die Vorlesungen zusammen.

56:11.610 --> 56:14.790
Java kennt acht elementare Datentypen, die haben wir im Laufe der

56:14.790 --> 56:15.850
Vorlesungen kennengelernt.

56:16.690 --> 56:19.950
Klassen spielen auch die Rolle von Datentypen, aber von Datentypen,

56:20.010 --> 56:21.330
die Sie eben selber deklarieren können.

56:23.030 --> 56:26.430
Mit jedem Datentyp sind bestimmte Operationen verbunden, die gehen

56:26.430 --> 56:29.990
oder die eben auch nicht gehen, wie wir das an diesem kleiner und

56:29.990 --> 56:32.390
größer gesehen haben, was zum Beispiel auf Strings eben nicht geht in

56:32.390 --> 56:32.850
unserem Quiz.

56:35.770 --> 56:38.850
Bei Klassen sind sogenannte Methoden, was das ist, in der

56:38.850 --> 56:39.950
Gästevorlesung mit verbunden.

56:41.630 --> 56:43.610
Wir haben Variablen kennengelernt.

56:43.770 --> 56:48.250
Variablen sind Namen für Speicherplätze und die können durch eine

56:48.250 --> 56:49.710
Zuweisung verändert werden.

56:49.710 --> 56:53.470
In der Regel, wenn ich mir ein Objekt erzeugen will, nämlich den

56:53.470 --> 56:55.870
Operator new, werden wir auch gleich nochmal genauer kennenlernen,

56:56.390 --> 56:59.630
dann ergibt er ein Objekt zurück und die Adresse im Speicher, wo

56:59.630 --> 57:02.650
dieses Objekt liegt, was mit new erzeugt wurde, das speichere ich dann

57:02.650 --> 57:03.570
mit einer Variable.

57:06.010 --> 57:08.730
Die Objektvariablen sind eigentlich Referenzen, das heißt also

57:08.730 --> 57:12.370
Speicheradressen, aber sie können im Prinzip außer mit einer Zuweisung

57:12.370 --> 57:13.650
nichts mit denen machen in Java.

57:14.590 --> 57:17.610
Und wie gesagt, das bewahrt Sie davor, schlimmere Fehler zu begehen.

57:18.730 --> 57:22.810
Und es gibt einen speziellen Referenzwert, das ist die 0 und das heißt

57:22.810 --> 57:24.010
kein Objekt.

57:27.530 --> 57:31.570
So, jetzt wären wir mit der Einheit zu Ende und würden auch gleich mit

57:31.570 --> 57:33.270
der Nummer 3 weitermachen,

57:37.680 --> 57:41.400
weil die nämlich auch sehr gut inhaltlich hier gleich anschließt.

57:54.390 --> 57:58.630
Und zwar haben wir eben schon dieses verdächtige Wörtchen new die

57:58.630 --> 58:01.070
ganze Zeit gesehen, was uns ein neues Objekt erzeugt.

58:01.690 --> 58:04.870
Das würde ich jetzt hier gerne in der Vorlesung nochmal etwas genauer

58:04.870 --> 58:05.270
erklären.

58:06.090 --> 58:11.090
Also wir hatten sowas gesehen wie Vector2D p ist gleich und dann new

58:11.090 --> 58:11.950
Vector2D.

58:12.170 --> 58:14.990
Jetzt könnte man sagen, was heißt das hier eigentlich im Einzelnen?

58:16.090 --> 58:19.290
Es passieren hier drei Sachen.

58:19.790 --> 58:25.450
Einmal deklariere ich eine Variable p vom Typ Vector2D.

58:27.150 --> 58:31.910
Dann erzeuge ich ein neues Objekt mit dem Wort new.

58:32.750 --> 58:37.510
Das heißt, wenn zur Laufzeit, wenn das Programm abläuft, diese Zeile

58:37.510 --> 58:43.090
ausgeführt wird, wird im Hintergrund Speicherplatz belegt mit einem

58:43.090 --> 58:51.330
Objekt vom Typ 2D und diese Stelle im Speicherplatz wird dieser

58:51.330 --> 58:52.770
Variable p zugewiesen.

58:52.770 --> 58:55.010
Genau wie wir das eben gesehen hatten bei diesen Objektreferenzen.

58:55.550 --> 58:59.290
Und in den nachfolgenden Zeilen definiere ich jetzt auch noch

58:59.290 --> 59:00.870
tatsächlich die Werte, die da drin stehen.

59:01.290 --> 59:05.290
Das x hat den Wert 4,0, das y hat den Wert 22,5.

59:07.350 --> 59:11.130
Jetzt ist das Ganze an der Stelle ein bisschen unschön und zwar

59:11.130 --> 59:16.050
deswegen, weil ich diese drei Dinge sehr sehr häufig in der Praxis

59:16.050 --> 59:17.270
immer gemeinsam machen will.

59:18.510 --> 59:22.270
Deklarieren, Objekt instanziieren und initialisieren mit Werten.

59:23.470 --> 59:27.590
Und die ersten beiden Sachen, deklarieren und instanziieren, das habe

59:27.590 --> 59:29.030
ich jetzt hier schon in einer Zeile gemacht.

59:30.210 --> 59:32.090
Jetzt würden Sie sich vielleicht ein bisschen wundern und sagen, naja,

59:33.450 --> 59:35.910
hier steht jetzt Vector2D als Typ von p.

59:36.470 --> 59:39.250
Hier dem new muss ich auch nochmal sagen, Vector2D, das ist doch

59:39.250 --> 59:40.690
irgendwie ein bisschen bescheuert.

59:40.770 --> 59:42.570
Da muss ich zweimal Vector2D hinschreiben.

59:44.530 --> 59:47.610
Die Antwort lautet, leider muss man das, aber es hat einen Grund.

59:47.810 --> 59:51.910
Und zwar ist der Grund der, hier könnten Sie hinter new noch andere

59:51.910 --> 59:53.950
Dinge hinschreiben und eben nicht Vector2D.

59:54.050 --> 59:56.630
Was aber, viel viel späterer Vorlesung.

59:58.410 --> 01:00:02.210
Für die Cracks unter Ihnen, die sowieso schon immer alles können, p

01:00:02.210 --> 01:00:05.950
ist der sogenannte statische Typ, das ist der, der einmal deklariert

01:00:05.950 --> 01:00:10.610
wurde für p und new ist der sogenannte dynamische Typ, der zur

01:00:10.610 --> 01:00:11.810
Laufzeit hier zugewiesen wurde.

01:00:11.810 --> 01:00:13.850
Und es gibt bestimmte Regeln in der Objektorientierung, die es

01:00:13.850 --> 01:00:17.230
erlauben, dass der dynamische Typ abweicht vom statischen Typ.

01:00:17.870 --> 01:00:20.770
Und das ist der Grund, weil das eben so sein kann, dass man hier

01:00:20.770 --> 01:00:22.170
zweimal das hinschreiben muss.

01:00:22.650 --> 01:00:25.690
Hier ist jetzt erstmal der Fall einfach, der statische Typ, Vector2D,

01:00:25.830 --> 01:00:27.890
ist gleich dem dynamischen Typ, Vector2D.

01:00:28.550 --> 01:00:31.230
Welt ist in Ordnung, aber wie gesagt, weil das nicht immer so sein

01:00:31.230 --> 01:00:32.390
muss, muss man es halt zweimal hinschreiben.

01:00:33.750 --> 01:00:36.930
Worauf ich aber hinaus will ist, das was hier noch nicht so schön ist,

01:00:37.730 --> 01:00:40.710
das x und y muss ich separat initialisieren.

01:00:40.710 --> 01:00:43.630
Und hier ist natürlich schon die Quelle für alles mögliche übel

01:00:43.630 --> 01:00:44.050
gegeben.

01:00:44.910 --> 01:00:45.350
Warum?

01:00:45.810 --> 01:00:46.450
Aus zwei Gründen.

01:00:46.570 --> 01:00:47.990
Erstens mal könnten Sie was vergessen.

01:00:49.030 --> 01:00:53.850
Sie könnten also vergessen, dass Ihr Vector2D x- und y-Koordinaten

01:00:53.850 --> 01:00:54.110
hat.

01:00:54.590 --> 01:00:55.890
Soll ich nur x initialisieren?

01:00:56.410 --> 01:01:00.170
Oder irgendein Schluffy-Baldurin ändert das mal auf Vector3D und

01:01:00.170 --> 01:01:03.470
vergisst aber hier das z dann noch mit zu initialisieren.

01:01:03.570 --> 01:01:06.810
Das heißt also, hier ist schon eine potenzielle Quelle von Fehlern da,

01:01:07.970 --> 01:01:13.030
weil das, was eigentlich zusammengehört, Deklaration, Instanzierung

01:01:13.030 --> 01:01:15.570
und Initialisierung hier leider getrennt ist.

01:01:15.710 --> 01:01:17.990
Und das sind natürlich immer Dinge, die getrennt sind in der Quelle

01:01:17.990 --> 01:01:18.950
von Inkonsistenzen.

01:01:19.250 --> 01:01:21.730
Entweder schon direkt beim Programmieren oder spätestens bei der

01:01:21.730 --> 01:01:23.810
Software -Evolution, wenn irgendwie Leute anfangen, im Code

01:01:23.810 --> 01:01:24.590
rumzuvorwerken.

01:01:27.390 --> 01:01:31.870
Deswegen hat man sich überlegt und gesagt, Moment mal, derjenige, der

01:01:31.870 --> 01:01:37.590
das Objekt P von dieser Klasse Vector2D nutzt, das ist ja

01:01:37.590 --> 01:01:40.370
möglicherweise jemand, der weiß gar nicht so genau, wie das intern

01:01:40.370 --> 01:01:43.330
aufgebaut ist, das Vector2D.

01:01:43.990 --> 01:01:46.270
Und das ist auch so ein bisschen die Idee gewesen, als wir Klassen

01:01:46.270 --> 01:01:49.630
deklariert haben, dass derjenige, der die Klassen nutzt, nicht immer

01:01:49.630 --> 01:01:51.950
genau wissen muss, wie die eigentlich intern funktionieren.

01:01:52.750 --> 01:01:54.310
Jetzt kann man sagen, das ist ja für die Schwächlinge.

01:01:54.830 --> 01:01:57.010
Ein richtiger Programmierer weiß doch gefälligst von allen Klassen,

01:01:57.090 --> 01:01:58.130
wie die intern funktionieren.

01:01:58.130 --> 01:02:00.090
Das ist aber eine ziemlich bescheuerte Haltung.

01:02:01.930 --> 01:02:05.450
Software-Systeme sind heute so groß, dass es natürlich überhaupt

01:02:05.450 --> 01:02:07.450
keinen einzelnen Menschen mehr gibt, der alle Klassen kennt.

01:02:07.690 --> 01:02:09.890
Sondern jeder hat nur seinen speziellen Bereich, wo er sich auskennt

01:02:09.890 --> 01:02:10.390
in der Software.

01:02:12.070 --> 01:02:13.910
Und keiner hat mehr den gesamten Überblick.

01:02:14.030 --> 01:02:18.130
Das heißt, wir kommen gar nicht umhin, mit einer Abstraktion, zum

01:02:18.130 --> 01:02:19.850
Beispiel einer Abstraktion durch Klassen zu leben.

01:02:20.050 --> 01:02:23.690
Wenn jemand Vector2D hinschreibt, sage ich, super, ich weiß, was ein

01:02:23.690 --> 01:02:26.910
Vector ist, wie der den intern implementiert hat, braucht mich als

01:02:26.910 --> 01:02:28.390
Nutzer gar nicht interessieren.

01:02:29.210 --> 01:02:32.490
Das heißt, ob der das jetzt mit x- und y-Koordinaten, also

01:02:32.490 --> 01:02:36.070
cartesianischen Koordinaten, realisiert hat, oder ob der den Vector

01:02:36.070 --> 01:02:39.850
mit Polarkoordinaten, sprich Ursprung und Winkel, implementiert hat,

01:02:40.490 --> 01:02:41.610
das will mich gar nicht interessieren.

01:02:41.710 --> 01:02:43.730
Hauptsache, ich kann einen Vector angeben und ich weiß, was ein Vector

01:02:43.730 --> 01:02:43.930
ist.

01:02:44.310 --> 01:02:46.110
Wie das innen drin funktioniert, mir erstmal egal.

01:02:46.630 --> 01:02:49.390
Das heißt, die Tatsache, dass dieser Vector innen drin mit x und y

01:02:49.390 --> 01:02:54.750
implementiert ist, das weiß zwar der Definierer von der Klasse Vector,

01:02:56.050 --> 01:02:58.990
es sollte aber nicht unbedingt der Nutzer davon genau wissen.

01:03:00.570 --> 01:03:02.230
Das ist das sogenannte Geheimnisprinzip.

01:03:03.010 --> 01:03:08.130
Sie kapseln in einer Klasse Entwurfsentscheidungen, wie zum Beispiel

01:03:08.130 --> 01:03:12.510
die Entscheidung, cartesianische Koordinaten zu verwenden, und wollen

01:03:12.510 --> 01:03:16.230
das Ganze so modellieren, dass es nachher, man diese

01:03:16.230 --> 01:03:18.630
Entwurfsentscheidung ändern kann, zum Beispiel Umstellung auf

01:03:18.630 --> 01:03:22.410
Polarkoordinaten, ohne dass alle Leute, die das verwenden, sich

01:03:22.410 --> 01:03:23.430
darüber Gedanken machen müssen.

01:03:23.490 --> 01:03:25.890
Dass sie nur an einer Stelle diese Änderungen machen.

01:03:26.670 --> 01:03:29.670
Und es dient, wie gesagt, der besseren Wartung ihres Software-Systems

01:03:29.670 --> 01:03:31.530
und es dient auch letztendlich der besseren Verständlichkeit.

01:03:32.330 --> 01:03:36.030
So, und hier ist dieses Geheimnisprinzip ziemlich krude verletzt.

01:03:37.150 --> 01:03:40.610
Hier schreibe ich hin, Vector2D ist gleich p gleich nur Vector2D,

01:03:40.690 --> 01:03:43.290
alles klar, prima, gut, kann ich auch machen, wenn ich nicht weiß, wie

01:03:43.290 --> 01:03:44.190
Vector innen drin funktioniert.

01:03:44.870 --> 01:03:47.010
Aber spätestens, wenn es jetzt hier in die Initialisierung geht, muss

01:03:47.010 --> 01:03:50.110
ich mir auf einmal Gedanken machen, hey, da ist ein x und ein y drin

01:03:50.110 --> 01:03:51.850
und das sind halt cartesianische Koordinaten.

01:03:52.370 --> 01:03:54.670
Und an jeder Stelle, wo ich das nochmal neu hinschreibe, also erstens

01:03:54.670 --> 01:03:57.550
mal muss ich es verstehen, und zweitens mal, wenn ich es jetzt

01:03:57.550 --> 01:03:59.930
mehrfach im Programm verstreuselt habe, muss ich halt bei der

01:03:59.930 --> 01:04:02.670
Umstellung jetzt auf Polarkoordinaten, da jedes Mal mit dem Editor

01:04:02.670 --> 01:04:03.530
rein und mit es suchen.

01:04:04.070 --> 01:04:05.290
Auch wieder eine Quelle von Fehlern.

01:04:06.770 --> 01:04:07.890
Und jetzt können Sie sagen, ja, ist ja trivial.

01:04:08.610 --> 01:04:10.870
Natürlich, drei Zeilen sind ziemlich trivial, aber wie gesagt, stellen

01:04:10.870 --> 01:04:14.570
Sie sich vor, die Komplexität heutiger Softwaresysteme kommt meistens

01:04:14.570 --> 01:04:17.870
nicht dadurch, dass ein Codefragment verwirrend komplex ist.

01:04:17.950 --> 01:04:19.090
Das kann sein, muss aber nicht.

01:04:19.230 --> 01:04:21.870
Die meiste Komplexität von Software heutzutage kommt einfach daher,

01:04:21.930 --> 01:04:23.690
dass sie schier unendlich groß ist und Sie einfach überhaupt keine

01:04:23.690 --> 01:04:26.190
reale Chance haben, die komplett zu lesen und zu verstehen.

01:04:26.570 --> 01:04:30.890
Weil einfach schon ein mittelgroßes kleines Anwendungsprogramm heute

01:04:30.890 --> 01:04:33.350
schon rucki-zucki hunderttausende von Zeilen codert.

01:04:33.450 --> 01:04:35.110
Da haben Sie überhaupt keine Chance, das zu verstehen.

01:04:35.970 --> 01:04:38.710
Und sowas, also Verletzungen des Geheimnisprinzips, ganz schlecht für

01:04:38.710 --> 01:04:39.430
die Verständlichkeit.

01:04:40.410 --> 01:04:44.610
Und deswegen gibt es sogenannte Konstruktoren und die fassen die

01:04:44.610 --> 01:04:48.450
Objekterzeugung und die Initialisierung der Attribute zusammen.

01:04:51.310 --> 01:04:53.730
Wieder ein neues Wort, Konstruktor.

01:04:54.430 --> 01:04:55.630
Also was macht ein Konstruktor?

01:04:55.650 --> 01:04:59.470
Ein Konstruktor erzeugt erstmal eine Instanz einer Klasse, wird mit

01:04:59.470 --> 01:05:03.790
new aufgerufen und, jetzt kommt der Gag, er dient zur Initialisierung

01:05:03.790 --> 01:05:04.430
der Werte.

01:05:07.830 --> 01:05:10.870
Und damit liegt er letzten Endes, wenn man so will, den Startzustand

01:05:10.870 --> 01:05:11.850
von einem Objekt fest.

01:05:12.070 --> 01:05:14.230
Dann kann mit dem Objekt an der Hand gemacht werden, werden wir gleich

01:05:14.230 --> 01:05:14.630
noch sehen.

01:05:15.150 --> 01:05:17.390
Aber erstmal gibt es einen definierten Startzustand.

01:05:18.930 --> 01:05:23.430
Die Konstruktoren müssen denselben Namen haben wie die Klasse, damit

01:05:23.430 --> 01:05:26.270
das Java-System rafft, dass das der Konstruktor ist, den er nutzen

01:05:26.270 --> 01:05:28.110
kann bei der Erzeugung mit new.

01:05:32.070 --> 01:05:35.170
Und erhalten die Anfangswerte des Objekts als Parameter.

01:05:35.930 --> 01:05:38.890
So, jetzt haben wir gleich das nächste Wort, Parameter, kennengelernt.

01:05:40.950 --> 01:05:43.310
Bevor wir jetzt zu einem Beispiel kommen, nochmal das mit dem

01:05:43.310 --> 01:05:44.290
Parameter schnell erklärt.

01:05:45.110 --> 01:05:47.890
Ein Parameter ist erstmal ein Platzhalter für beliebige Werte.

01:05:48.110 --> 01:05:51.090
Also erstmal ist ein Parameter nichts anderes wie eine Variable, aber

01:05:51.090 --> 01:05:55.910
keine frei rumflottierende Variable, sondern es gehört immer zu einer

01:05:55.910 --> 01:05:56.710
Funktion dazu.

01:05:56.710 --> 01:05:58.810
Schauen wir uns das mal hier an, am Beispiel.

01:05:59.550 --> 01:06:03.210
f von x ist gleich x mal Sinus x Quadrat.

01:06:05.130 --> 01:06:10.830
Der Parameter ist x und der wird dann an diesen Stellen halt

01:06:10.830 --> 01:06:11.350
verwendet.

01:06:12.610 --> 01:06:17.390
Oder auch mehr Parameter haben, g von x, y ist gleich, hier als

01:06:17.390 --> 01:06:19.570
Beispiel, x Quadrat plus y Quadrat.

01:06:20.330 --> 01:06:24.710
Das sind alles Funktionen, x und y spielen die Rolle von Parametern.

01:06:24.710 --> 01:06:26.530
Jetzt unterscheidet man zwei Begriffe hier.

01:06:27.670 --> 01:06:30.290
Das ist auch relativ wichtig, dass Sie das einmal verstanden haben.

01:06:30.810 --> 01:06:33.190
Formale Parameter und aktuelle Parameter.

01:06:33.790 --> 01:06:37.850
Der formale Parameter ist der Parameter, der bei der Deklaration der

01:06:37.850 --> 01:06:38.690
Funktion hier steht.

01:06:39.150 --> 01:06:42.490
Also das x hier, in f von x.

01:06:43.370 --> 01:06:46.870
Der aktuelle Parameter ist der Wert, den Sie jetzt beim Aufruf

01:06:46.870 --> 01:06:47.410
mitgeben.

01:06:47.870 --> 01:06:51.270
Zum Beispiel also, wenn ich sage f von 3, wenn ich das Ganze aufrufe,

01:06:52.150 --> 01:06:54.790
dann ist die 3 der sogenannte aktuelle Parameter.

01:06:55.130 --> 01:06:58.130
Wie gesagt, formaler Parameter ist derjenige, der den Parameter

01:06:58.130 --> 01:07:01.550
hinschreibt bei der Deklaration der Methode oder der Funktion.

01:07:02.050 --> 01:07:04.330
Wie eben hier dem f von x oder dem g von x, y.

01:07:05.050 --> 01:07:07.850
Aktueller Parameter ist der Parameter, der hingeschrieben wird, wenn

01:07:07.850 --> 01:07:09.290
ich das Ganze nutze und aufrufe.

01:07:10.790 --> 01:07:13.010
So, jetzt kommen wir wieder zurück zu unseren Konstruktoren.

01:07:13.430 --> 01:07:14.950
Dafür haben wir ja die Parameter erstmal eingeführt.

01:07:17.070 --> 01:07:22.170
Sie erinnern sich, wir hatten vorletzte Vorlesung diese Klasse

01:07:22.170 --> 01:07:24.710
Vector2D definiert.

01:07:25.430 --> 01:07:29.970
Wir hatten die Werte x und y als Fließkommazahlen da drin definiert

01:07:29.970 --> 01:07:32.390
und erstmal hatten wir weiter nichts gemacht.

01:07:33.850 --> 01:07:36.510
Jetzt muss ich also bei dem Konstruktor, wenn ich einen Konstruktor

01:07:36.510 --> 01:07:41.370
schreibe für Vector2D, dafür sorgen, dass alle Variablen, also alle

01:07:41.370 --> 01:07:44.230
Attribute da drin, x und y, belegt werden.

01:07:45.530 --> 01:07:48.810
Und da könnte ich mir also hier einen Konstruktor überlegen.

01:07:48.970 --> 01:07:52.650
Konstruktor muss immer den Namen der Klasse haben, Vector2D also.

01:07:52.910 --> 01:07:56.010
Jetzt hingeschrieben als Funktion, Klammer auf, erster formaler

01:07:56.010 --> 01:08:00.030
Parameter x0, zweiter formaler Parameter y0.

01:08:00.870 --> 01:08:07.750
Dann weise ich dem x, das ist hier das x dann, das x0 zu und dem y

01:08:07.750 --> 01:08:10.170
weise ich das y0 hierzu als Parameter.

01:08:10.510 --> 01:08:13.830
Und damit habe ich im Prinzip alle Attribute, die ich habe, in meiner

01:08:13.830 --> 01:08:15.610
Klasse mit Werten anständig belegt.

01:08:15.710 --> 01:08:18.830
Und zwar mit den Werten, die als Parameter reingegeben werden beim

01:08:18.830 --> 01:08:19.070
Konstruktoraufruf.

01:08:19.910 --> 01:08:25.230
Zum Beispiel könnte ich jetzt new Vector2D hinschreiben in meinem

01:08:25.230 --> 01:08:28.990
Programm und zum Beispiel 2,0 als Fließkommazahl oder 3,0 als

01:08:28.990 --> 01:08:30.130
Fließkommazahl angeben.

01:08:30.570 --> 01:08:31.830
Das heißt das f jedes Mal hier hinter.

01:08:32.270 --> 01:08:36.110
Und habe damit dann die aktuellen Parameter hier gesetzt beim Aufruf

01:08:36.110 --> 01:08:37.990
und die werden dann dem x und y zugewiesen.

01:08:38.710 --> 01:08:40.450
Das ist erstmal keine Hexerei.

01:08:50.020 --> 01:08:52.860
Also hier ist eine geschweifte Klammer.

01:08:53.980 --> 01:08:57.080
Achso hier, ja genau, Sie haben recht.

01:08:57.500 --> 01:09:00.860
Die ist bei der Überblendung hier, genau da ist sie.

01:09:01.300 --> 01:09:02.160
Gut aufgepasst.

01:09:03.080 --> 01:09:05.400
Ist jetzt dummerweise uns verschütt gegangen.

01:09:09.940 --> 01:09:13.740
Also baue ich hier den Konstruktor ein in unsere Klasse.

01:09:14.060 --> 01:09:15.900
Nur damit Sie sehen, wo der auch hinkommt, der Konstruktor.

01:09:17.560 --> 01:09:21.700
Class Vector2D, geschweifte Klammer auf, float xy, also erst die

01:09:21.700 --> 01:09:25.140
Attribute und dann wird ein Konstruktor angegeben.

01:09:25.280 --> 01:09:27.780
Und das ist der, der jetzt beide Variablen mit Werten belegt.

01:09:29.300 --> 01:09:35.720
Was man jetzt häufig macht, naja das mit dem x0 und y0, das kann man

01:09:35.720 --> 01:09:36.100
so machen.

01:09:36.620 --> 01:09:39.220
Aber der Grund, warum man hier jetzt einen anderen Namen als x und y

01:09:39.220 --> 01:09:42.580
hinschreibt, ist ja der, weil x und y schon als Variablennamen hier

01:09:42.580 --> 01:09:43.340
vergeben sind.

01:09:43.340 --> 01:09:46.680
Ich kann nicht im selben Geltungsbereich zweimal dieselben

01:09:46.680 --> 01:09:47.860
Variablennamen vergeben.

01:09:48.820 --> 01:09:54.300
Und damit man dieses Problem umgeht, kann ich das x und das y hier,

01:09:54.860 --> 01:09:59.480
also die da oben, referenzieren mit sys.x und sys.y.

01:10:00.540 --> 01:10:04.760
Und sys bezieht sich immer auf meine aktuelle Objektinstanz.

01:10:06.800 --> 01:10:10.080
Und damit kann ich dann hier x und y verwenden und dann diese

01:10:10.080 --> 01:10:11.500
Zuweisung machen, das würde gehen.

01:10:13.720 --> 01:10:17.880
Was technisch passiert ist, ich deklariere hier x und y, die

01:10:17.880 --> 01:10:20.220
überdecken die x und y.

01:10:20.500 --> 01:10:23.140
Das heißt, das kann ich machen, aber dann könnte ich ohne das sys

01:10:23.140 --> 01:10:24.520
diese Zuweisung nicht mehr machen, ist ja klar.

01:10:24.780 --> 01:10:27.780
Wenn hier x gleich x steht und y gleich y, fragt sich der Compiler ja

01:10:27.780 --> 01:10:29.280
auch, guten Tag, was haben Sie sich denn hier gedacht?

01:10:29.500 --> 01:10:33.920
Ist ja eh klar, dass Sie meinten, mit dem x meine ich auf der Seite,

01:10:34.000 --> 01:10:37.040
aber das x da oben und mit dem y hier meine ich natürlich das y da

01:10:37.040 --> 01:10:37.280
oben.

01:10:37.280 --> 01:10:40.520
Um genau das zu sagen im Compiler, schreiben Sie sys.davor.

01:10:49.210 --> 01:10:52.750
Wenn Sie jetzt eine Klasse hinschreiben, wie wir das in der ersten

01:10:52.750 --> 01:10:54.990
Veröffentlichung gemacht haben, die noch gar keinen Konstruktor hat,

01:10:56.990 --> 01:10:59.550
dann ist es natürlich schon so, dass Sie trotzdem Instanzen davon

01:10:59.550 --> 01:11:00.350
erzeugen wollen.

01:11:01.050 --> 01:11:03.030
Sie haben jetzt aber keinen Konstruktor angegeben und was macht dann

01:11:03.030 --> 01:11:03.330
Java?

01:11:03.850 --> 01:11:06.410
Java erzeugt automatisch dann einen Konstruktor.

01:11:06.410 --> 01:11:09.590
Wenn Sie keinen Konstruktor angeben, wenn er keinen findet in Ihrer

01:11:09.590 --> 01:11:13.070
Klassendeklaration, also keine Methode, keine Funktion, die den Namen

01:11:13.070 --> 01:11:15.390
der Klasse selber hat, dann wird einer generiert.

01:11:16.230 --> 01:11:18.050
Und warum kann Java das immer generieren?

01:11:18.230 --> 01:11:22.210
Naja, weil Java für alle möglichen Arten von Variablentypen immer

01:11:22.210 --> 01:11:26.130
weiß, oder es mal definiert wurde, welcher Wert dann da initialisiert

01:11:26.130 --> 01:11:26.570
werden soll.

01:11:26.650 --> 01:11:28.350
Das wird einfach mal festgelegt im Sprachstandard.

01:11:29.250 --> 01:11:32.570
Und das ist bei Boolean einfach eine brutale Festlegung.

01:11:32.570 --> 01:11:35.010
Hätte genauso gut auch true sein können, ist aber halt false.

01:11:36.850 --> 01:11:43.550
Für die Integerwerte byte, short und int wird 0 reingeschrieben.

01:11:44.810 --> 01:11:49.890
Für long wird auch 0 reingeschrieben, aber 0l, was also l heißt, die 0

01:11:49.890 --> 01:11:50.790
für longs.

01:11:52.090 --> 01:11:56.730
Für float wird 0,0f hingeschrieben, was die fleece-komma-zahl 0,0 für

01:11:56.730 --> 01:11:58.070
float -Variablen ist.

01:11:58.610 --> 01:12:01.230
Für double wird 0,0 reingeschrieben, wenn man hier nämlich nichts

01:12:01.230 --> 01:12:03.610
dahinter schreibt, dann ist klar, dass die 0,0 für doubles ist.

01:12:04.670 --> 01:12:05.810
Was auch eine fleece-komma-Zahl ist.

01:12:06.110 --> 01:12:09.030
Für Characters wird Unicode 000 reingeschrieben.

01:12:09.850 --> 01:12:12.990
Und für Objektreferenzen, also Dinge, wo man eigentlich erwartet, dass

01:12:12.990 --> 01:12:15.190
da mal ein Objekt drin liegt, wird 0 reingeschrieben.

01:12:15.470 --> 01:12:17.430
Als konstante 0 für eine Referenz.

01:12:18.270 --> 01:12:22.570
Durch diese Festlegung kann natürlich Java immer einen Konstruktor

01:12:22.570 --> 01:12:23.310
generieren.

01:12:23.550 --> 01:12:26.650
Ob der sinnvoll ist, das weiß ich natürlich nicht.

01:12:26.650 --> 01:12:27.930
Das hängt immer sehr vom Kontext ab.

01:12:28.010 --> 01:12:30.290
Das kann natürlich sein, dass das nicht so schlau ist, wenn das mit

01:12:30.290 --> 01:12:32.650
den Werten initialisiert wird, weil die vielleicht gar keine Bedeutung

01:12:32.650 --> 01:12:33.610
haben in einer Anwendung.

01:12:34.930 --> 01:12:37.470
Klar, in dem Fall sollten Sie selber sich einen Konstruktor schreiben.

01:12:37.950 --> 01:12:41.490
Wenn Sie sagen, das ist vollkommen okay, wenn das Objekt am Anfang mit

01:12:41.490 --> 01:12:43.210
diesen Werten initialisiert ist, ist klar, da brauchen Sie sich nicht

01:12:43.210 --> 01:12:46.250
die Mühe machen, selber einen Konstruktor zu schreiben, weil das geht

01:12:46.250 --> 01:12:46.890
ja automatisch.

01:12:49.410 --> 01:12:55.330
So, jetzt kann man aus Bequemlichkeit sich auch mehrere Konstruktoren

01:12:55.330 --> 01:12:56.390
pro Klasse deklarieren.

01:12:57.010 --> 01:12:58.110
Wir haben das jetzt hier gesehen.

01:12:58.330 --> 01:13:01.950
Es gibt Vector2D mit dem Float, wie wir das eben hatten.

01:13:03.750 --> 01:13:07.810
Und wir haben jetzt hier nochmal Vector2D angegeben mit nur einer

01:13:07.810 --> 01:13:08.010
Fließkommazahl.

01:13:08.810 --> 01:13:09.310
Und was passiert?

01:13:09.470 --> 01:13:11.170
Naja, das Y wird immer auf 0 gesetzt.

01:13:11.170 --> 01:13:14.430
Es kann ja sein, dass wenn ich Vektoren verwende, dass es häufig so

01:13:14.430 --> 01:13:17.670
ist, dass ich zum Beispiel damit nur eine Art Entfernungsangabe machen

01:13:17.670 --> 01:13:20.530
will und mir eigentlich die eine Dimension reicht.

01:13:20.670 --> 01:13:23.730
Und wenn zum Beispiel sowas der Fall ist, dann brauche ich mir nachher

01:13:23.730 --> 01:13:30.030
nicht mehr mühsam hinschreiben Vector2D, p ist gleich new, Vector2D,

01:13:30.590 --> 01:13:35.750
dann Klammer auf, von mir aus, 3,0,0f, sondern ich schreibe einfach

01:13:35.750 --> 01:13:41.230
nur 3 hin, also 3,0f, und brauche dann nicht jedes Mal noch die zweite

01:13:41.230 --> 01:13:44.490
Konstante hier, wenn das E0 werden soll, immer angeben.

01:13:44.730 --> 01:13:46.590
Und dann habe ich hier ein bisschen Bequemlichkeit, indem ich dann

01:13:46.590 --> 01:13:48.250
immer das Ganze hier fest hinsetze.

01:13:48.710 --> 01:13:53.430
Und was Sie hier auch sehen ist, Sie können an der Stelle mit Sys

01:13:54.800 --> 01:13:57.240
quasi diesen Konstruktor hier oben aufrufen.

01:13:58.180 --> 01:14:03.040
Sie haben hier die Parameter x0 und 0,0f, das heißt zwei Float-Zahlen.

01:14:03.040 --> 01:14:05.380
Dann weiß er, jetzt ist dieser Konstruktor damit gemeint, jetzt wird

01:14:05.380 --> 01:14:06.060
der aufgerufen.

01:14:06.960 --> 01:14:11.640
Sie könnten es auch so machen hier, Sie könnten x mit x0 belegen und y

01:14:11.640 --> 01:14:12.540
mit 0,0f.

01:14:12.880 --> 01:14:18.660
Das ist ein bisschen eleganter, weil Sie hier sagen, falls das jetzt

01:14:18.660 --> 01:14:20.080
mal geändert wird aus irgendeinem Grund,

01:14:24.540 --> 01:14:27.780
brauche ich hier das an einer Stelle ändern und da rufe ich es dann

01:14:27.780 --> 01:14:28.320
wieder auf.

01:14:28.820 --> 01:14:30.240
Und das ist natürlich ein bisschen netter an der Stelle.

01:14:32.480 --> 01:14:35.920
Eine Sache sollten Sie aber wissen, in dem Augenblick, wenn Sie einen

01:14:35.920 --> 01:14:42.340
Konstruktor explizit angeben, egal welchen, wird keiner mehr

01:14:42.340 --> 01:14:42.840
generiert.

01:14:43.140 --> 01:14:45.780
Und das heißt, in dem Augenblick, wenn Sie einen Konstruktor angeben,

01:14:45.820 --> 01:14:49.540
wie wir das jetzt hier gemacht haben, ist dieser Aufruf plötzlich

01:14:49.540 --> 01:14:50.280
nicht mehr möglich.

01:14:50.960 --> 01:14:54.960
p ist gleich new Vector2D mit leeren Klammern, weil es keinen

01:14:54.960 --> 01:14:58.080
Parameter hat, den Default-Konstruktor aufrufen, also der, der alles

01:14:58.080 --> 01:15:02.200
auf 0 oder diese definierten Anfangswerte setzt, der ist aber nicht

01:15:02.200 --> 01:15:02.640
mehr da.

01:15:02.860 --> 01:15:03.920
Und warum ist der nicht mehr da?

01:15:04.260 --> 01:15:05.880
Weil Sie selber welche angegeben haben.

01:15:06.600 --> 01:15:09.240
Also das ist halt so eine Falle, wo man manchmal reintappt, weil man

01:15:09.240 --> 01:15:10.260
denkt, naja, das geht ja immer.

01:15:10.820 --> 01:15:13.320
Stimmt nicht, es geht nur, wenn ich gar keinen Konstruktor definiert

01:15:13.320 --> 01:15:13.440
habe.

01:15:13.520 --> 01:15:16.780
Wenn ich sobald ich einen definiert habe, wird der nicht mehr erzeugt

01:15:16.780 --> 01:15:19.080
und dann muss ich ihn mir entweder von Hand hinschreiben oder einfach

01:15:19.080 --> 01:15:19.640
nicht verwenden.

01:15:21.140 --> 01:15:23.920
Meistens ist nicht verwenden die schlauere Idee, weil ich habe ja

01:15:23.920 --> 01:15:26.240
gerade Konstruktoren angegeben, weil der Default-Konstruktor keinen

01:15:26.240 --> 01:15:26.800
Sinn macht.

01:15:30.270 --> 01:15:34.150
So, jetzt haben wir mit diesen Konstruktoren etwas schon

01:15:34.150 --> 01:15:38.210
kennengelernt, nämlich wir haben Code in eine Klassendeklaration

01:15:38.210 --> 01:15:39.050
reingeschrieben.

01:15:39.390 --> 01:15:43.590
Wir haben also Attribute definiert und ich habe Code definiert.

01:15:43.710 --> 01:15:46.350
Jetzt war das aber ein besonderer Code, nämlich der Code, der durch

01:15:46.350 --> 01:15:47.770
new aufgerufen wird.

01:15:49.470 --> 01:15:51.830
Es gibt aber natürlich noch anderen Code, den ich auch gerne

01:15:51.830 --> 01:15:54.910
reinschreiben möchte, andere Funktionalitäten, die ich meiner Klasse

01:15:54.910 --> 01:15:55.830
hinzufügen will.

01:15:55.830 --> 01:15:58.510
Ich will vielleicht zum Beispiel Vektoren addieren oder multiplizieren

01:15:58.510 --> 01:16:00.830
untereinander und nicht nur erzeugen.

01:16:01.750 --> 01:16:03.570
Und genau das passiert mit Methoden.

01:16:04.170 --> 01:16:07.450
Damit ist es nun möglich, die Werte der Attribute auszulesen und

01:16:07.450 --> 01:16:10.090
wieder zu ändern und zurückzuschreiben oder auch Ergebnisse nach außen

01:16:10.090 --> 01:16:12.730
zu geben, die auf Berechnungen basieren, die in der Klasse

01:16:12.730 --> 01:16:13.510
durchgeführt werden.

01:16:15.290 --> 01:16:19.510
Und das Ganze ist eigentlich schon so ähnlich wie das, was wir mit dem

01:16:19.510 --> 01:16:22.750
Konstruktor gemacht haben, nur dass ich jetzt nicht den Klassenname

01:16:22.750 --> 01:16:24.930
hinschreibe, sondern einen beliebigen Methodennamen.

01:16:25.750 --> 01:16:29.750
Und es gibt Rückgabetypen, das heißt, das Ganze sieht dann so aus.

01:16:30.210 --> 01:16:31.310
Ein Beispiel erst, z.B.

01:16:31.930 --> 01:16:34.750
int convert to Fahrenheit, int Celsius.

01:16:35.070 --> 01:16:37.510
Was das macht, ist relativ schnell verständlich hier.

01:16:37.590 --> 01:16:41.210
Es wird ein Celsius-Integer-Wert genommen und der wird in einen

01:16:41.210 --> 01:16:46.990
Temperaturwert der Einheit Fahrenheit umgerechnet.

01:16:48.950 --> 01:16:50.410
Und was steht hier?

01:16:50.470 --> 01:16:52.250
Das Ergebnis ist wieder ein Integer.

01:16:52.250 --> 01:16:57.550
Das ist wieder eine Ganzzahl und der Parameter vom Integer ist auch

01:16:57.550 --> 01:16:59.550
eine Ganzzahl und das ist der Name der Methode.

01:17:00.670 --> 01:17:04.070
Und wenn die Methode definiert wird, also reingeschrieben wird, was

01:17:04.070 --> 01:17:08.290
tut sie tatsächlich, steht hier erstmal die Formel zum Umrechnen von

01:17:08.290 --> 01:17:12.610
Celsius in Fahrenheit und dann steht dieses neue Wort, was sie noch

01:17:12.610 --> 01:17:13.650
nicht kannten, Return hier.

01:17:14.310 --> 01:17:20.370
Return bedeutet, das ist das Ergebnis, das wird jetzt als Integer dem

01:17:20.370 --> 01:17:21.990
Aufrufer davon wieder zurückgegeben.

01:17:21.990 --> 01:17:23.690
Und das ist auch das allgemeine Schema.

01:17:24.490 --> 01:17:27.050
Es gibt einen Rückgabe-Typen, Methoden-Namen und sogenannte formale

01:17:27.050 --> 01:17:29.050
Parameter, die haben wir eben schon kennengelernt bei den

01:17:29.050 --> 01:17:29.630
Konstruktoren.

01:17:30.490 --> 01:17:34.770
Und dann kommt ein Methoden-Rumpf und wenn der Rückgabe-Wert ein

01:17:34.770 --> 01:17:37.750
definierter Rückgabe-Wert ist, es gibt auch das Wort Void, das lernen

01:17:37.750 --> 01:17:41.030
wir später mal kennen, das heißt kein Typ, dann muss man ein Return

01:17:41.030 --> 01:17:41.790
immer am Ende haben.

01:17:46.090 --> 01:17:48.130
Genau das eine machen wir noch.

01:17:51.490 --> 01:17:56.470
Die sogenannte Signatur der Methode, das ist dieser Rückgabe-Typ,

01:17:56.810 --> 01:17:59.870
Name, Parameter-Typ, das ist die sogenannte Signatur.

01:18:00.270 --> 01:18:02.090
Das ist, wenn man so will, die Schnittstelle der Methode.

01:18:02.190 --> 01:18:03.790
Darüber läuft die gesamte Kommunikation.

01:18:03.910 --> 01:18:07.850
Damit wird deklariert, welche Werte als Parameter reinkommen und auch

01:18:07.850 --> 01:18:11.210
wieder was als Werte möglicherweise zurückkommt über den Rückgabe-Typ.

01:18:15.240 --> 01:18:17.060
Das ist das, was auch genau hier steht.

01:18:17.060 --> 01:18:24.300
Und hier sehen wir einmal eine Int-Variante davon oder auch mit

01:18:24.300 --> 01:18:29.300
Double, also mit Gleitkommarithmetik, wenn wir Dezimalzahlen vorkommen

01:18:29.300 --> 01:18:29.920
lassen wollen.

01:18:32.860 --> 01:18:37.160
Und wenn ich jetzt die Methode so definiert habe, kann ich jetzt hier

01:18:37.160 --> 01:18:38.640
einen Aufruf machen, z.B.

01:18:38.720 --> 01:18:40.160
dem Wert c,

01:18:44.500 --> 01:18:50.900
den Wert 15 zuteilen, dann f, das ist jetzt ein bisschen schräg an der

01:18:50.900 --> 01:19:00.700
Stelle, und dann kann ich f ist gleich ConvertToFahrenheit c aufrufen.

01:19:01.920 --> 01:19:05.980
f ist eine Integer-Variante, dem wird der Wert, der zurückkommt, von

01:19:05.980 --> 01:19:10.960
ConvertToFahrenheit von dem Wert c, was 15 war, zurückgewählt.

01:19:11.080 --> 01:19:14.180
Das heißt also, nachher steht hier ein f, der Fahrenheit-Wert drin,

01:19:16.100 --> 01:19:18.500
der 15°C entspricht.

01:19:20.460 --> 01:19:21.700
Warum muss das ein Int sein?

01:19:21.820 --> 01:19:26.020
Naja, dieses c muss ein Int sein, weil Sie hier auch Integer

01:19:26.020 --> 01:19:26.760
deklariert haben.

01:19:27.280 --> 01:19:29.900
Also das muss vom Typ passen, der Rückgabe-Typ muss der Zuweisung

01:19:29.900 --> 01:19:30.720
natürlich hier passen.

01:19:31.380 --> 01:19:33.500
Was passen heißt, so ein Typ besprechen wir auch mal in einer ganz

01:19:33.500 --> 01:19:34.160
fernen Vorlesung.

01:19:35.800 --> 01:19:42.100
Und es gibt jetzt hier verschiedene Beispiel-Methoden, die man mal

01:19:42.100 --> 01:19:42.980
deklarieren kann.

01:19:43.460 --> 01:19:46.060
Das habe ich Ihnen mal angegeben, einfach um zu zeigen, wie das

01:19:46.060 --> 01:19:46.520
aussieht.

01:19:46.960 --> 01:19:51.420
Also Fahrenheit, Volumen vom Zylinder und wenn ich jetzt zum Beispiel

01:19:51.420 --> 01:19:58.120
das Ganze in Java deklariere, da gibt es schon Fahrenheit und für die

01:19:58.120 --> 01:20:02.980
Fläche eines Zirkels mit Abhängigkeit vom Radius könnte man hier die

01:20:02.980 --> 01:20:07.580
von Ihnen bekannten Schule Pi mal R² eingeben und das zurückgeben an

01:20:07.580 --> 01:20:07.920
der Stelle.

01:20:08.720 --> 01:20:12.180
Oder das Volumen vom Zylinder, dann kann das nutzen und das Ganze noch

01:20:12.180 --> 01:20:14.060
mit der Höhe multiplizieren, die Fläche.

01:20:14.920 --> 01:20:17.740
Und so sehen dann eben Aufrufe aus, also wenn Sie Converter-Fahrenheit

01:20:17.740 --> 01:20:20.720
38,0°C eingeben, bekommen Sie den Wert 104.

01:20:22.740 --> 01:20:27.540
Area-Zirkel 2,0 ist eben das Quadrat mit Pi multipliziert, gerundet,

01:20:27.700 --> 01:20:29.400
dieser Wert 12,5664.

01:20:29.400 --> 01:20:34.440
Und das Volumen vom Zylinder berechnet sich dann daraus 1,5 mal diesen

01:20:34.440 --> 01:20:37.020
Wert und liefert daher diese 18,84.

01:20:37.940 --> 01:20:40.700
So, an der Stelle belassen wir es und machen dann beim nächsten Mal

01:20:40.700 --> 01:20:40.920
weiter.

01:20:41.020 --> 01:20:41.340
Vielen Dank.

