Herzlich Willkommen zur letzten Vorlesung in diesem Jahr,
SE1. Was ihr hier seht, ist ein Beitrag zum Tuttel Graphics Creativity Contest.
Und die Gewinner stehen auch jetzt fest. Die werden auch
heute hier präsentiert. Dieser Beitrag ist leider nicht unter den Gewinnern,
obwohl er wirklich sehr schön ist und von vielen,
von vielen sehr gut gewählt wurde,
sehr gut eingeschätzt wurde.
Sieht natürlich hübsch aus
Ein rotierendes Sternenfeld. Allerdings haben wir bei einigen Einreichungen gesagt,
naja, da ist vielleicht doch ein bisschen,
na nicht geschummelt worden, aber nachgeholfen worden.
Und deswegen, also zum Beispiel in diesem Fall ist es so,
dass wenn man sich den Dom Türmer anguckt,
dass der erstmal ganz harmlos aussieht.
Wenn man dann aber hier sich die, in der Seitenleiste das anzeigen lässt,
dann sieht man, dass das ein ziemlich langer Quelltext ist.
Und wir haben einfach vermutet, dass das hier diese ganzen Zeilen ja,
nicht von Hand programmiert wurden. Aber es ist künstlerisch extrem wertvoll,
also den Quelltext auch noch ansprechen zu formatieren,
also großer Respekt, großer Respekt,
aber den konnten wir nicht gewinnen lassen,
weil das generierter Code ist und das fanden wir nicht fair
für Tavallevel 1 und 2. Nichtsdestotrotz
ist das ein Applaus wert für Patrick Winter,
vielen Dank
Ich habe hier noch ein weiteres, das ich zeige.
Von Melvjohansen und Sebastian Dösel. Das ist das hier.
Das ist etwas, was nur mathematisch versierte Menschen zu schätzen wissen.
Das ist ein Ausschnitt aus der Mandelbrotmängel. Die Mandelbrotmenge ist
nach einem Mathematiker benannt, Mandelbrot, Benoit, Mandelbrot.
Und der hatte so, ja, sich mit komplexen Zahlen beschäftigt.
Und dann gab es irgendwann jemanden, der hatte die Idee,
Mensch, wir können doch mal die Ebene der komplexen Zahlen grafisch visualisieren.
Und das hier ist quasi die Ebene der komplexen Zahlen.
Und alles, was schwarz ist, gehört zur Mandelbrotmenge und alles
im Randbereich, da weiß man es nicht so genau.
Da kann man immer weiter reinzoomen. Das haben die hier
auch teilweise implementiert, jetzt nicht interaktiv.
Aber die haben halt auch ein bisschen geschummelt,
weil sie die Turtle angepasst haben.
Also in dem Sinne konnten die dann auch nicht gewinnen.
Aber auch das ist ein wunderschöner Beitrag, vielleicht nochmal
ganz kurz gezeigt.
Also hier Mandelbrot
Ja, also toll. Einmal den Ball, ein paar bitte.
Auch wenn ihr... Ich werde gleich noch in der Pause
noch einen Beitrag zeigen, der auch quasi außer Konkurrenz läuft.
Ja, eine Frage. Bitte? Die zweite Klasse ist
nicht für die richtige Anregung. Die ganze Menge für Freiheit
. Aber man muss die Zeichnack, ah, okay,
oh, oh, seht ihr.
Möglicherweise habe ich das gar nicht genau genug gelesen.
Was musst du jetzt machen hier? Ja,
so eine Länge der größeren Punktwerte. Vergrößerer Umpunkt,
da muss ich einen Punkt angeben.
Einfach den hier.
Oh, oh. Oh, ja, das wollen wir
uns zumindest noch angucken. Und jetzt, was passiert jetzt
? Das rechnet, heißt ein bisschen, das dauert.
Das dauert ein bisschen länger. Gut, ich bin hier so
ein bisschen knapp mit der Zeit in der Vorlesung leider.
Wir können das ja so machen, diejenigen, die bereit sind,
dass ihre, oh, oh, jetzt geht's los hier.
Diejenigen, die bereit sind, dass ihre Projekte noch ins
Kommensee kommen, die können wir ja ins Kommensee stellen.
Also dann kann sich das jeder auch noch mal angucken.
Oh, hier sieht man das jetzt,
wie das jetzt so nach und nach immer schärfer rausgeschält wird.
Dieses Mandelbrunnering wird auch als Apfelmännchen bezeichnet,
weil die so ein bisschen aussieht wie so ein Apfelmännchen,
ihr wisst ja, wen Apfelmännchen aussieht.
Es ist ein ganz cooles Zeug. Das ist so
die Schnittstelle zwischen Mathematik und Pop-Art. Aber die Leute,
das waren zufällige Mathematiker aus Bremen,
die haben dafür weltweit Ansehen und so weiter,
weil das ist irgendwie eine ganz coole Kiste,
dass man das so visualisieren kann.
Die haben das in den 90er-Jahren ganz, ganz großartig vorangetrieben.
Diese Visualisierung. Ja, das ist cool, aber ich
muss es jetzt leider beenden. Aber das ist nochmal,
das ist nochmal deutlich eindrucksvoller als das,
was ich gerade gezeigt habe.
Das ist gut
Ja, man möchte eigentlich, man möchte gar nicht mehr aufhören, ne?
Es tut mir jetzt in der Seele weh, das beenden zu müssen.
Okay, also, dann geht es hier erstmal weiter.
Wie gesagt, in der Pause zeige ich noch einen Beitrag außer Konkurrenz
und dann, ja, dann steigen wir nochmal ein.
Was haben wir bis jetzt gemacht? Naja,
wir haben schon drei Stufen von SE1 hinter uns.
Stufe 1 haben wir uns noch relativ einfache Klassen angeguckt.
Stufe 2 haben wir uns angeguckt, wie Klassen sich gegenseitig benutzen können,
haben die das Konzept von Referenzen in Java eingeführt.
Stufe 3 haben wir dann gesagt,
eine Schnittstelle kann explizit formuliert werden mit einem Interface.
Und sein Interface kann unterschiedlich implementiert werden und haben da unterschieden
zwischen Schnittstelle und Implementation und haben uns dann auch überlegt,
wie kann man denn sowas auch testen,
indem man nur die Schnittstelle testet oder indem man auch in die Schnittipplementation reinguckt.
Und wir haben uns angesehen, wie man Sammlungen benutzt.
Das heißt, wir haben Sammlungen eingeführt,
das Collections Framework von Java, vor allen Dingen Mengen und Listen.
Und jetzt beginnt Stufe 4. Heute erster Teil von Stufe 4.
Und wir haben bisher relativ viel Sprachkonzepte von oder Sprachmechanismen
von Java eingeführt
Das machen wir heute auch nochmal. Und dann ist es aber eigentlich so,
dass wir danach nur noch mit diesen Mechanismen üben.
Das heißt, wir werden uns verschiedene Dinge betrachten.
Vor allen Dingen werden wir uns ansehen, wie man Sammlungen
implementieren kann. Das ist relativ spannend, weil man da
sehr viel lernen kann über Algorithmik, über effiziente Implementationen.
Und was man braucht, wenn man Sammlungen vernünftig implementieren will,
dann braucht man fast unausweichlich, nicht ganz, aber fast a race.
Und Race sind ein Konzept, was wir von Java bisher
nicht eingeführt haben. Bewusst, wir haben erst gesagt,
benutzt lieber die Sammlung aus dem Java Collections Framework.
Aber heute geht es um Race. Also heute gucken wir
uns Race an. Das wird eine relativ technische Vorlesung.
Ich werde einfach erzählen, wie Race in Java funktionieren.
Ich werde aber auch ein bisschen davon abstrahieren und dann sagen, naja,
wie ist es denn allgemein mit Arrace und so weiter.
Ich fange mit einem Beispiel an. Nehmen wir an,
wir haben eine Temperatur, Messgerät in einer hochsee-tauglichen Boje.
Sowas gibt es ja, dass Geowissenschaftler sowas aussetzen,
um Temperaturen zu messen. Und man kann sich vorstellen,
davon sind irgendwie mehrere tausend auf den Weltmeeren ausgesetzt.
Und die können ihre Position durchfunken und die können aber außerdem
irgendwie Messwerte festhalten. Nehmen wir mal an, die können
noch nicht die Messwerte irgendwie weiter funken, vereinfachte Annahme.
Und es gibt also Sensoren, die messen den ganzen Tag die Temperatur.
Und weil die Dinge relativ teuer sind, weil der Speicher auch sehr,
sehr robust sein muss, ist der relativ klein,
sodass wir da nur ungefähr tausend Messwerte speichern können.
Wir können auch meinetwegen sagen 10.000 oder 100.000, ist wurscht.
Es geht erstmal darum, dass der Speicher sehr knapp ist.
Und man eigentlich die Messwerte möglichst direkt im Speicher abbilden will
Wir wollen da irgendwie die letzten 1000 Messungen dann ablegen in dem Speicher.
Und wir wollen dann möglicherweise auch Maximum und Minimum finden in dieser Liste von Zahlen.
Ja, und für die Realisierung in Java bietet sich
ein Array an. Warum bietet sich ein Array an?
Weil Arrays ein sehr speichernahes Konzept sind. Das ist etwas,
was man sich klarmachen sollte,
dass eigentlich Rays nur so ein Ausschnitt von dem Speicher,
auf dem wir ja normalerweise arbeiten, widerspiegeln.
Etwas etwas konkreter für die Anwendung. Es ist eine Sammlung gleichartiger Elemente
. Und auf die Elemente wird über einen Index zugegriffen.
Und üblicherweise Dean Array zur Realisierung von Listen mit fester Größe.
Die Listen mit flexibler Größe kennengelernt letzte Woche. Und jetzt
geht es bei den Arrays eher um Listen mit fester Größe.
Und wie gesagt, die abstrahieren von einem zusammenhängenden Speicherbereich,
das ist auch ganz wichtig bei den Listen und den Mengen,
könnt ihr nicht sicher sein,
dass die Elemente irgendwo an einer Stelle im Speicher zusammenliegen
Das ist einfach nicht garantiert. Irgendwie gibt es da verschiedene Implementationen und die verteilen das,
was da abgelegt wird, an verschiedenen Stellen im Speicher.
Bei einem Ray könnt ihr sicher sein, dass das,
was in dem Array drin ist, an einem Speicherbereich liegt.
Das heißt, wenn wir den Speicher,
auf dem wir ja üblicherweise in einem Computer arbeiten,
also der Hauptspeicher, uns vorstellen,
als ein ziemlich langes Band von Zellen,
die man von null bis irgendwie Max indizieren kann,
dann ist so ein Array hier so ein Segment im Speicher,
zusammenhängende Speicherzellen und dann indiziert man
diese Speicherzellen beginnend bei null
Das habe ich schon bei den Listen letzte Woche erzählt,
dass in der Informatik gerne mit null beginnend indiziert wird.
Bei Arrays ist es jetzt vielleicht noch nachvollziehbarer,
weil die Adresse dieser Speicherzelle hier, der ersten,
des Arrays, liegt bei Adresse null, bei Air Adresse N.
Und wenn man da den Index drauf addiert,
dann kriegt man sozusagen genau die richtige Zelle.
Also bin ich für die erste Zelle null drauf,
an der kriege ich genau diese Zelle und so weiter.
So kann ich sozusagen hier sehr gezielt auf den Speicher zugreifen.
Das hat auch bestimmte Vorteile, in dem Sinne,
dass auf den meisten Rechnerarchitekturen solche Indexbasierten Zugriffe im Speicher
sehr schnell sind
Das heißt also, man kommt da sehr schnell an diese Elemente ran.
Das zahlt sich aus, zum Beispiel bei einem typischen Anwendungsbeispiel
von Race, nämlich wenn man Bilddaten verarbeiten will.
Bilder, wenn ihr die in einem Speicher, in einem Computer abspeichert,
dann sind das digital eben zweidimensionale Strukturen von einzelnen Bildpunkten.
Und die Bildgröße, also Bild-Seilen und Bildspalten,
die ist bei einem Bild üblicherweise relativ statisch.
Also hier irgendwie, was weiß ich, 300 Zeilen,
300 Spalten und 600 Zeilen oder ähnliches
Und wenn man Bildverarbeitung auf solchen Punkten machen will und sowas kennt ihr,
wenn ihr mit Photoshop schon mal gearbeitet habt, dann wisst ihr,
wenn ich so ein großes Bild habe und will jetzt einen Filter anwenden auf das Bild,
dann ist das nichts weiter als auf jeden Bildpunkt in diesem Bild,
wird nach und nach der Filter angewendet.
Das heißt, man muss dadurch alle, ja,
wenn man da jetzt Bilder hat von heutzutage, die Kameras,
locker dreimal 5.000 Zeilen, also mehrere Megabyte, mehrere Millionen Bildpunkte,
wenn man da eben halt auf jedem Bildpunkt was machen will und es ist schon wichtig,
dass man schnell an die Bildpunkte rankommt,
um das einigermaßen effizient zu machen.
Ihr habt sicherlich schon mal gesehen,
dass es so auf manche Filter gibt,
die durchaus länger brauchen auf
so einem Bild
Bildverarbeitung ist ein ganz cooles Thema. Und deswegen haben wir
natürlich auch wieder für Blue Jay diese Woche für die Übung
ein kleines Projekt mit Bildverarbeitung vorgesehen. Das heißt also,
ihr werdet ab morgen dann in den Übungen mit Schwarz-Weiß-Bildern umgeht.
Ich zeige hier mal so einen Konstruktor.
Ich kann also hier mir so ein Schwarz-Weiß-Bild erzeugen.
Da kann ich einen Pfad angeben. Zum Beispiel hier kiss.giv
. Und dann sieht man, oh ho, ja,
ja, ich mache das mal zu hier
Ja, wie hier haben wir das Bild? Das ist
genau das Bild, was hier auch auf der Folie ist.
Und dieses Bild ist jetzt hier aber als Java-Objekt abgelegt.
Das heißt, dass hier diese Referenz zeigt auf ein Objekt von der Klasse Schwarz-Weiß-Bild.
Und diese Klasse hält intern die ganzen Bildpunkte. Ja,
und jetzt kann ich hier tatsächlich Dinge drauf machen.
Ich kann hier Operationen dran ausführen, wie ihr das kennt.
An einem Objekt kann ich Operationen ausführen. Also kann ich
hier zum Beispiel aufrufen, mach es mal dunkler.
Jetzt gibt es hier für diese Schwarz-Weiß-Bilder einfach Farbwerte,
also jeder Bildpunkt hat einen Farbwert von null schwarz bis 255 weiß.
Wenn ich sage, mach es mal 40 Helligkeitsstufen dunkler,
dann wird das Bild ein bisschen dunkler und das kann man ganz gut sehen,
weil ich ja hier auf der Folie das Originalbild noch habe,
dann sieht man, dass das hier ein bisschen dunkler geworden ist.
Ich kann das nochmal aufrufen, also dunkler, ja,
hier um 40 Helligkeitsstufen und das ist dann noch dunkler geworden.
Das kann man eben halt tatsächlich dann,
alles Mögliche kann man da drauf machen,
man kann hier das invertieren, man kann hier sich,
man kann das, was kann man nochmal horizontal spiegeln,
scheint jetzt nicht implementiert zu sein.
Nochmal horizontal spiegeln scheint nicht so aus, sich auszuwirken,
habe ich vielleicht nicht implementiert
Und ja, in der Implementation ist das, juhu, ein Array.
Das ist ein zweidimensionales Array. Wir werden uns zweidimensionale Race heute auch noch angucken,
aber erstmal gucken wir uns gleich eindimensionale Arrays an. Aber man sieht dann hier,
dass tatsächlich, wenn irgendwie so ein Filter angewendet wird,
also zum Beispiel heller, hier fehlt noch was,
na gut, dunkler, ist dunkler da,
dunkler ist da, haben wir eben gesehen, ja,
dann wird hier in zwei Vorschleifen irgendwie über die Zeilen und die Spalten dieser Bitpunkte gegangen,
auf jedem Bitten wird irgendwas gemacht.
Das ist das, was ihr in den Übungen machen werdet.
Soweit so gut. Ein anderes Anwendungsbeispiel sind Spielfelder.
Spielfelder fester Größe. Race haben die Eigenschaft, dass sie
fester Länge definieren, also fester Größe. Das heißt,
das ist oft unflexibel, wenn man nicht weiß,
wie groß die Listen so werden, mit denen man arbeiten will.
Also je nach Anwendungsproblem, das man so hat,
braucht man diese flexiblen Listen aus dem Collections Framework.
In anderen Fällen reicht es aber völlig aus mit einem statischen,
mit einer statischen Liste zu arbeiten.
Wenn ich mir so ein TikTok-Toe-Spielfeld angucke,
dann ist das eben halt relativ einfach.
Das sind dreimal drei Zellen. Oder ein Vier-Gewinn-Spielfeld hat sechsmal
sieben Zellen. Oder ein Schachbrett hat achtmal acht Zellen,
also 64 Zellen. Und da muss ich ihn jetzt nicht
mir wahnsinnig flexible Listen überlegen.
Das kann ich auch einfach mit einem Array machen
Und wenn ihr euch dann noch mal erinnert,
wir hatten hier einen Blue Jay, ich glaube,
in Woche 5 hatten wir diese Tic-Tac-Tor-Implementation,
die sah ungefähr so aus wie diese hier.
Und da hatten wir noch keine Interfaces,
aber da haben wir dann gesagt, es gibt ein Interface-Spielfeld,
das haben wir ja dann auch später noch eingeführt für Tic-Tac-Toren.
Dann gab es ein Spielfeld, Gepflicht als Implementation und in Spielfeldgeflecht
hat im anderen Spielfeld Zeilen, das war so ein bisschen umständlich.
Kein Mensch würde wirklich so ein 3x3-Spielfeld auf diese Weise implementieren. Das war nur,
um zu zeigen, dass man sowas auch objektorientiert machen kann,
indem man sich diese Zeilen in dem Spielfeld modelliert als einzelne Also
eine Zeile mit drei Zellen drin und dann drei davon hat,
dann hat man ein Spielfeld mit neun Zellen.
Das war aber ziemlich umständlich, da hat man auch gesehen,
wenn ich jetzt hier auf so eine Spielfeldzeile zugegriffen habe,
dann musste ich da irgendwie so einen Case und einen Switch machen,
Switch Case und das war irgendwie,
das war nicht so richtig schön,
wenn ich auf irgendwie eine Zeile und eine Spalte zugreifen wollte.
Das geht deutlich hübscher mit Arays und das gucken wir uns heute an.
Gut, das ist eine Übersicht über Arays and Java,
ist ein bisschen anders als im Skript.
Ich habe so ein paar Kleinigkeiten geändert,
aber im Großen und Ganzen ist es das,
was man sich ganz gut merken kann.
Arays sind Behälter
Behälter für eine geordnete Reihung gleichartiger Elemente.
Und auf die Details gehe ich jetzt nicht ein,
weil ich das alles jetzt hier, das ist also eine Übersichtsfolie,
wenn ihr irgendwann nochmal lernen wollt für eine Klausur,
könnt ihr euch das nochmal in Ruhe hier zusammengefasst ansehen.
Wir gehen das jetzt tatsächlich alles mal ein bisschen detailliert durch.
Das erste, was man wissen muss, wenn man mit
Arrays in Java arbeitet. Diese Arrays sind speziell unterstützt. Ja,
da gibt es so eine Spezialsyntax mit so eckigen Klammern,
die sehen wir gleich auch noch,
haben wir auch eben schon ein bisschen gesehen.
Das heißt, diese Arrays sind irgendwie in die Sprache integriert,
aber aus objektorientierter Sicht sind die genauso Objekte
Das Erste, was wir uns jetzt betrachten, sind Array Variabler.
Ihr wisst, ihr müsst für alles,
was ihr verarbeiten wollt, in Jabo euch eine Variable deklarieren.
Und wenn die Race-Objekte sind, dann wissen wir, ja,
in Java ist ja alles irgendwie über Objekte und dann über Referenzvariablen zu Manipulieren.
Das heißt, die Array-Variablen, die ihr deklariert,
die sind immer Referenzvariablen. Das heißt, der Typ dieser
Varianten, der ist quasi als Array von Element-Typ deklariert.
Hier ist ein Beispiel in Array. Sowas kann ich natürlich
jetzt auch live hier mal machen
Das kann also hier hinschreiben, Int, Array.
Das ist sozusagen der Typ. Dann nenne ich das Ding irgendwie
Int, Arra. Und dann kann ich dir auch gleich
mal zeigen, dass das wirklich eine Referenz variable ist.
Ich kann da nämlich Nalds zuweisen. Nald ist ja eine Dinal-Referenz. So,
und schon habe ich hier mein Int-Array und kann das
auch abfragen oder sagt er mir, das ist Nald.
Klar, steht ja auch Nald drin. Das heißt,
wir haben genau die Situation, die auf der Folie hier,
meine Variable referenziert auf Nüscht. Die Länge oder die Größe
des Arrays wird bei der Deklaration nicht angegeben. Das sage ich deshalb,
weil das in anderen Sprachen ein bisschen anders ist,
zum Beispiel in Pascal, wer Pascal kennt,
Da muss man bei der Deklaration einer Array-Variablen schon gleich mit angeben,
wie groß denn das Array ist.
Statisch bei der Deklaration der Variablen. Java ist da ein
bisschen flexibler. Sehen wir gleich. Syntax für die Ray-Deklaration
, für eine eindimensionale Array-Deklaration. Also der Elementtyp,
dann die eckigen Klammern und dann der Name der Array-Variablen.
Hier sind zwei Beispiele. Einmal mit Int als elementaren Typ
als Typ der Elemente in dem Array. Und hier einmal,
wo man anscheinend eine Person hat, das heißt,
das sind hält, also mit einem Objekttyp als Elementtyp,
ein Array von Personen.
Okay, jetzt können wir noch nicht viel machen mit so einer Variablen.
Wir wissen ja, wir brauchen immer irgendetwas, worauf die Referenzvariable verweist.
Ja, und das ist wie mit allen Objekten,
die muss man in Java ja immer mit New erzeugen und auch Array-Objekte,
also diese Behälter-Objekte, die müssen explizit erzeugt werden.
Also ich kann jetzt hier tatsächlich einen Ausdruck hinschreiben,
New in 8. Das kann ich einfach so hinschreiben.
Ist ein Ausdruck, liefert mir eine Referenz auf ein
neues Objekt
Und dann kann das Ding hier hinlegen. Dann habe ich
hier mein Int-Array. So. Ja, und jetzt kann ich
mir das Ding hier in BlueJ angucken. Das ist,
sagen wir, relativ eingeschränkt, was man damit machen kann.
Ich kann jetzt hier nur inspizieren und es entfernen.
Jetzt habe ich aber tatsächlich mein Int-Array verweisend auf ein New Int 8,
also auf ein, das ist das Array-Objekt hier,
das ist der Behälter und meine Referenzvariable verweist jetzt darauf.
So. Die Syntax auch wieder, man braucht ein New
Dann muss der Typ, der Element-Typ angegeben werden,
von dem das Array sein soll. Also der Zellentyp quasi,
dann die eckigen Klammern und dazwischen ein Ausdruck,
wohlgemerkt ein Ausdruck, der festlegt, wie groß das Array ist.
Das heißt, beide Array-Erzeugung lege ich wirklich fest,
wie groß ist das Array? In diesem Fall hier New In10,
ein Array mit zehn Zellen für Int-Werte oder ein Array für Personen.
Und da ist hier einfach als Beispiel ein X angegeben,
um zu zeigen, naja, es kann halt irgendein beliebiger Ausdruck sein,
der auch erst zur Laufzeit ausgewertet wird.
Also es muss nicht zur Übersetzungszeit schon feststehen,
wie groß das Array ist
Okay, wenn man ein Array erzeugt, also so ein Behälter,
dann sind die Zellen in dem Behälter alle initialisiert.
Das ist in Java zum Glück so definiert. Und dann gibt es
wieder andere Sprachen, die machen das ein bisschen anders.
In C Plus zum Beispiel habt ihr das nicht immer garantiert.
In Java ist das garantiert. Und zwar mit den Default-Werten,
die ihr kennt, für die primitiven Typen,
also für Int ist das null, für Bully & Falls,
für Referenztypen ist es nall.
Das heißt, wenn wir uns jetzt hier dieses Objekt mal angucken,
was wir gerade erzeugt haben, mit New & 8,
kann ich einen Doppelklick drauf machen,
Objektinspektor poppt auf
Und ich kann mir das angucken und ich sehe hier,
acht Zellen, hier alle mit dem Wert null belegt.
Ich habe ja nichts angegeben bei der Erzeugung. Okay,
man kann, und das ist ganz cool bei Arrays in Java,
beide Deklarationen der Variablen, einen sogenannten Array Initializer mit angeben.
Das heißt, man kann hier so in geschweiften Klammern
quasi eine Belegung für die Zellen mit angeben.
Also wenn ich jetzt hier diesen Ausdruck mir angucke oder diese Deklaration,
hier wird ein Interray deklariert, vom Typ Interray.
Und hier wird dann direkt gesagt, ja, da sollen diese Werte drinstehen.
Da kann man also wirklich die Werte angeben durch Komma getrennt, in geschweiften Klammern.
Das ist wunderbar. Geht aber leider in Java nur an der Stelle,
wo eine Ray variable deklariert wird. Das heißt,
wenn ich jetzt versuche, hier meine Interray-Variable,
die ich ja schon habe, in Array,
die ist immer noch null, weil ich hier die Falsche genommen habe,
muss ich jetzt irgendwie überlegen, ich habe die jetzt,
das ist doof.
Wenn ich jetzt diese Array-Variablen versuche hier etwas zuzuweisen.
Die ist schon deklariert, die Variable. Und jetzt schreibe ich hier
irgendwie eins, zwei, drei, vier, fünf hin.
Irgendwie sowas. Das geht so nicht. Dann sagt der
illegal start-up Expression. Was ich aber machen kann, ist,
ich kann hier jetzt mir einfach eine neue Variable deklarieren,
die nenne ich jetzt einfach mal Into Ray 2.
Und die kann ich tatsächlich vorbelegen mit diesen Werten. Das heißt,
an dieser Stelle deklariere ich eine Referenzvariable vom Typ Interray und lasse
die gleich auf ein neu erzeugtes, zeugtes Ray-Objekt verweisen.
Ein Behälter, an dem die Zahlen von 1 bis 5 drinstehen.
Das müsste also so gehen. Also wenn ich jetzt sage
, Ray 2. Dann habe ich hier eine Objektreferenz.
Das ist jetzt ein bisschen unglücklich benannt.
Also in Array 2 hier rechts ist hier links in 1
und dann kann ich hier wieder den Objektinspektor mir anzeigen lassen.
Da sind da tatsächlich die Werte 1, 2,
3, 4, 5 drin. Also auch genauso,
wie es auf der Folie zu sehen ist.
Okay. Die Indizierung ist ganz wichtig, habe ich schon
gesagt, bei Arrays, genau wie bei Listen.
Man beginnt bei null. Das heißt,
die erste Zelle hat den Index 0 und so weiter.
Gültige Indiziers eines Arrays sind so mit 0 bis längs minus 1. Das heißt,
ich kann von einem Array mir die Länge geben lassen.
Ich kann also von einem Array-Objekt, das ja eine feste Größe hat,
kann ich mir immer sagen lassen, wie groß ist es denn?
Das heißt also, hier kann ich jetzt bei Interray,
kann ich jetzt... Interray 2.längs.
Und das ist jetzt ganz komisch. Ich schreibe da jetzt
keine runden Klammern dran. Das ist kein Operationsaufruf,
sondern das ist ein Zugriff auf ein konstantes,
eine konstante Exemplarkonstante, auf eine, ja, ein konstantes Exemplarfeld.
So, da sagt er mir jetzt zum Beispiel fünf.
Das heißt, das Array-Objekt hat die Größe fünf Zellen und
das kann ich jederzeit abfragen
Auch sehr effizient, kein Methodenaufruf dazwischen. Effizienz ist wichtig bei Arrays.
Und das heißt, die gültigen Indizes werden in diesem Fall
bei diesem fünf Elemente großen Array 0 bis 4. Gut.
Schreibender und lesender Zugriff auf die Array-Zellen.
Das ist ganz wichtig, dass man ja so ein,
so eine Schreibweise mit diesen eckigen Klammern, wo man tatsächlich darauf zugreift.
Ich kann also tatsächlich an dieser Stelle jetzt hier schreiben,
in Array 2, gib mir doch mal den Inhalt an Zellenposition
3. Was kommt da jetzt raus? Ja,
wer weit pfifft mit Zahl an den Kopf?
Genau. 1, 2, 3, 4 steht drin.
Und beziehungsweise sogar 5, 1, 2, 3,
4, 5. Und in der dritten Zelle ist es also die vierte Zelle eigentlich.
Man muss immer plus minus 1 fürchterlich. Informatik plus minus 1
, ganz schrecklich. So, hier ist also die 4 drin.
Ich habe also jetzt lesend auf eine Zelle des Array-Objektes zugegriffen.
Das ist also hier so auf der rechten Seite einer Zuweisung
, kann ich sowas tun.
Aber ich kann natürlich auch auf der linken Seite das Ding
hinschreiben und kann sagen, schreibt da mal was rein.
Ich kann also auch hier jetzt sagen,
in Array
Von die Zelle 3, zähle ich mit dem Index drauf.
Also die vierte Zelle, da soll jetzt mal die 17
reingeschrieben werden. Kann ich so machen. Das heißt,
jetzt habe ich hier da die 17 drin stehen.
Ich konnte das also auch beschriften. Dafür steht das natürlich dann auf der linken Seite,
wenn da etwas auf der linken Seite steht,
an der Zuweisung, ist das immer das Ziel einer Zuweisung.
Gut, das ist erstmal relativ zentral. Dann habe ich gesagt,
in einem Array darf der Elementtyp, ein primitiver Typ sein,
das sind die acht primitiven Typen in Java,
die ihr kennt.
Oder es kann
ein beliebiger Objekttyp sein
Das ist ein ganz fundamentaler Unterschied, mal wieder.
Das heißt, immer wenn wir Referenzen im Spiel haben,
müssen wir aufpassen. Für die primitiven Typen ist es relativ einfach.
Da werden die Werte wirklich direkt in dem Array-Objekt gespeichert.
Also wenn ich hier sowas habe mit Temperaturen, mit Double-Werten,
dann oder Double-Werten, dann stehen die hier tatsächlich direkt in dem Array-Objekt drin.
Wenn ich aber ein Array von Personen habe,
dann steht in dem Array selbst, stehen nur Referenzen.
Und die Objekte sind nochmal irgendwo woanders.
Meistens auf dem Hieb, eigentlich immer. Das heißt also,
ganz wichtig, so ein Array-Objekt enthält entweder primitive Typen,
wenn der Element typrimitiv ist oder Referenzen auf Objekte
Gut, jetzt gibt es so ein paar typische Fehler,
die man machen kann. Ich kann bei so einem Array natürlich
einen falschen Index verwenden. Klassischer Fehler, ich habe ein Array,
der größte, was habe ich hier, fünf.
Das Ding hat die Größe 5, mein Interrate
2. Wenn ich da jetzt in Array von fünf zugreifen will,
weil ich denke, das Ding hat ja fünf Elemente,
also müsste ich auf Zelle 5 auch zugreifen können,
dann knallt mir das um die Ohren.
Gibt eine Exception, Java, Lang, Null Pointer Acception.
Das ist komisch, das ist eine Ninal Pointer Acception gibt,
eigentlich sollte es eine Das ist falsch, was ich hier geschrieben habe.
In Array 2 war das, glaube ich. Danke für den Hinweis
. Hat jemand aufgepasst. Wenn das andere Interray war sowieso null,
da habe ich noch gar nichts drin gehabt in Array.
Aber diese Referenz variable and Array 2, die verweist auf ein Objekt.
Und wenn ich da auf die 5 zugreife,
dann kriege ich eine Java-Lang Array Index out of Bounds Exception.
Ganz schön lang. Und das ist aber das,
was ich eigentlich hier gerade erzeugen wollte. Okay, typischer
Fehler, gern gemacht. Dann der nächste typische Fehler,
wenn ihr eine Array-Variable deklariert habt, also zum Beispiel hier Exemplarvariable,
eine Variable Numbers, die ein Interray sein soll.
Und dann schreibt ihr irgendwo direkt Numbers von 0 soll 42 sein. Ja,
das geht nicht, weil das Objekt, das ihr da beschriften wollt,
an der Zellenposition 0, das ist noch gar nicht da.
Das gibt eine Null-Porter-Acception. Das heißt, ihr müsst natürlich
so eine Array erstmal erzeugen, bevor ihr es benutzen könnt.
Ganz elementar, wenn man, wie gesagt,
wenn man das mit den Referenzen verstanden hat,
ist das einfach nur Beat another Object Indirection,
aber ihr müsst es natürlich, sagen wir,
üben und ihr werdet in den Übungen des Häufering,
öfteren nochmal in solche Fehler reinlaufen.
Das haben wir die letzten Jahre eigentlich immer erlebt.
Das ist keine Überraschung. Gut, weiterer typischer Fehler ist,
bei den Race, wo der Elementtyp ein Objekttyp ist.
Das heißt, wo in den Zellen des Ray-Objektes Referenzen drin sind.
Das war ja dieses andere Bild eben mit den Personen.
Da kann ich vielleicht das Objekt erzeugt haben.
Also hier habe ich jetzt meine Variable,
meine Array-Variale konnten vom Typ Array von Konto.
Dann habe ich mir auch tatsächlich ein Ray-Objekt erzeugt.
New Konto 4, das ist das Objekt hier.
Der Behälter für die Ray-Zellen
Aber in den Array Sale steht noch nichts drin. Wenn ich jetzt sage,
Konto 00.1 zahlen, dann führt das einfach ins Leere.
Das ist also sozusagen nur eine Indirektion mehr,
als ihr es normalerweise kennt, wenn ihr eine Referenzvariabel habt,
die zeigt auf nüscht, dann gibt es eine Nightpointer Acception.
Das sind alles klassische typische Fehler. Gut. Gibt es
soweit erstmal Fragen dazu, so Arrays,
ist alles soweit nachvollziehbar, oder?
Ja, scheint so zu sein. Keine Fragen. Dann
gucken wir uns mal an, wie man typischerweise auf einem
Array etwas mit jedem Element in dem Array tut
Das heißt also, wenn man mit einer Vorschleife über einen Array iteriert,
dann meistens um alle Elemente des Arrays zu bearbeiten.
Und dabei wird eben halt diese öffentliche Exemplar konstante längst benutzt.
Das heißt, hier haben wir mal so ein Beispiel,
eine Methode Print Array bekommt als formalen Parameter eine Referenz auf einen Interrain.
Und was macht sie? Sie hat eine Vorschleife, fängt bei null an.
Das ist der erste gültige Index in jedem Array in Java.
Und solange dieser Index kleiner ist als die Länge,
wir haben gelernt, Größe 5,
dann habe ich als maximal Index 4,
dann kann ich sozusagen hier von 0 bis 4 durch ein Array durchlaufen und dann kann ich das auch ausgeben.
Das heißt, ich frage von dem Parameter dynamisch die Größe
ab und kann dann tatsächlich durch alle Elemente durchgehen.
Das ist keine Hexenkunst. Dass diese Benutzung für eine Vorschleife,
um etwas auf allen Elementen zu machen,
das nennen wir auch ein Programmiermuster.
Ein Programmiermuster ist ein Muster, wie man etwas in einer konkreten Programmiersprache macht.
Also zum Beispiel in Java ist es typischerweise so,
wenn ihr sowas seht,
so geht man über alle Zellen
in einem Array
Vor allen Dingen dann, wenn man an den Zellen auch wirklich
was verändern will. Hier werden die Zellen nur ausgelesen,
wenn man auch was reinschreiben will, ist das sehr schlau,
dass mit dieser Art von Schleife zu machen.
Es gibt nämlich auch die erweiterte Vorschleife für Race.
Diese sehr schönen, knapp beschreibbare Schleife,
die sieht sehr ähnlich aus. Wir haben die gleichen Methodenkopf,
diese Methode Print Array bekommt eine Referenz auf ein Interrain.
Und schreibt hier einfach for intcar für jedes K in diesem Interray.
In diesem Interray, also das liest sich wieder genauso,
wie wir sonst auch, wird hier irgendwas gemacht.
Das ist mir dann das Gleiche,
was auf der vorigen Folie stand
Aber wie gesagt, aufgepasst, diese Schleifenart ist nicht geeignet,
wenn ihr am Array selbst irgendwas machen wollt,
weil ihr habt sozusagen den Zugriff auf das Array nicht mehr in Schleifenrumpf,
habt ihr nur noch das einzelne Element und wirklich nur den Wert des einzelnen Elements nicht mehr die Zelle,
wenn ihr die Zelle im Zugriff behalten wollt und da irgendwie mit dem Index zugreifen wollt,
dann solltet ihr die andere Schleife nehmen,
die normale Vorschleife.
Ihr habt auch keinen Schleifenindex hier,
das habt ihr auch so ähnlich schon gesehen.
Gut, nehmen wir mal hier so ein Beispiel,
ich möchte in einem Ray
den minimalen Wert finden
Ich liefere den minimalen Wert im gegebenen Array und habe am Anfang gesagt,
diese Temperatur-Boje, da möchte ich jetzt tatsächlich mal irgendwie Minimalwert rausfinden.
Also habe ich hier meine, ich übergebe an eine Methode
Finde Minimum, meine Referenz auf das Array.
Und dann sage ich hier, na gut,
mein Minimum, mein bisheriges Minimum ist Integer Max Value,
das ist der größte Integer-Wert, den wir in Java darstellen können.
Und dann gehe ich tatsächlich einfach durch alle Elemente in dem Array durch.
Und Frage ist die Zelle an der Position I,
kleiner als das bisherige Minimum,
dann ist das neue Minimum jetzt
der Inhalt dieser Zelle
Und am Ende habe ich dann in dem Min in der Variablen
den minimalen Wert abgelegt. Okay. Hier ist mal eine
Benutzung davon. Also ich lege hier ein Ray ein.
My Array, ein Array der Größe C. Dann schreibe ich
in die Zelle 0-1, 2 die Werte rein.
20, 30, 20, 40 und 30. Dann rufe ich hier,
finde Minimum auf und lasse mir dann ausgeben, was da rauskommt.
An dieser Stelle benutzen wir doch mal Storesi.
Ihr habt den Code gesehen, hier ist der Code.
Ich zeige den gleich nochmal. Wir machen jetzt mal
eine kleine Abstimmung. Hier, SE1, Vorlesung
Laden. Welcher Wert wird in der letzten Zelle ausgegeben?
In der letzten Zeile, schon in der letzten Zelle,
sondern in der letzten Zeile. Also hier, wenn ihr
euch das anguckt, das ist die Benutzung von unserer Minimum-Methode.
Und jetzt gebe ich hier mal als mögliche Antworten 020,
40 oder es gibt eine Acception.
Könnt ihr den anderen Quelltext auch sehen?
Ich kann das hier noch ein bisschen zur Seite schieben.
Das ist hier, das ist der Code,
den ihr aufruft
Da wird das Array erzeugt. Hier werden die Wette gesetzt.
Dann wird hier gesagt, finde Minimum. Und dann,
ja. Und die Frage ist, kommt da jetzt raus,
0, 20, 40 oder geht da irgendwas schief?
Gibt es eine Exception? Ist das als Aufgabenstellung erstmal klar?
Ich denke schon. Der Quelltext ist hier noch ein bisschen zu sehen.
Ich gucke mal ganz kurz, wie viele schon dabei sind.
50 haben schon ihre Stimme abgegeben. Was passiert denn hier
? Was passiert hier? Das ist immer irgendwie so,
das ist so richtig,
Java-Code lesen können und nachvollziehen können, was da passiert.
Da ist es ganz zentral für SE1. 80 Stimmen haben wir,
86, ich glaube so bei 100 würde ich dann gerne wieder dem Ende entgegengehen.
Kommt, gebt noch eure Stimmen ab. Sehr schön.
So, jetzt haben wir über 100 Stimmen.
Jetzt gucken wir uns erst mal an, was da so
die Verteilung ist. Okay, immerhin 50 Prozent sagen,
der Wert ist null
Und ungefähr ein Viertel sagt, es ist 20,
weil das ist ja das Minimum von den Werten,
die wir da in das Array reingeschrieben haben.
Und 20 Prozent sagen, naja, es gibt eine Exception,
weil wir ja, vielleicht war die Idee, ja,
ich habe hier in dem Code,
an dieser Stelle ja nur in drei Zellen was reingeschrieben.
Und vielleicht gibt es einen Fehler, wenn dadurch alle Zellen durchgegangen wird,
weil diese Schleife geht ja durch alle Zellen des Arrays durch.
Und da muss man jetzt genau aufpassen,
diese Schleife geht tatsächlich bis zur Länge. Das heißt,
der Behälter wird komplett durchsucht,
der Behälter wird aber angelegt mit zuerst 10 Nullen und
dann werden an drei Stellen werden andere Werte reingeschrieben
Das heißt, tatsächlich ist das hier auch die richtige Antwort.
Das heißt, also die meisten von euch haben das richtig gesehen.
Okay, sehr schön. Ja, ich kann das nochmal erklären.
Also, hier unten haben wir eine Array-Referenz, Variable.
My alright, die zeigt auf eine Array von Int-Werten.
Hier legen wir ein Array an der Größe 10.
Wenn ein Array der Größe 10 angelegt wird,
sind alle Zellen automatisch initialisiert mit dem Default-Wert
Bei Int zum Beispiel Null. Das heißt,
wir haben eine Ray mit 10 Nullen drin.
Dann schreiben wir hier in die Zellen 0-1 und 2,
die Werte 20, 40 und 30 rein.
Und jetzt übergeben wir der Methode finden dem Minimum eine Referenz auf dieses Array.
Und diese Methode finden dem Minimum, die weiß nicht,
was wir an drei Stellen reingeschrieben haben, was interessiert die nicht.
Die durchsucht das ganze Array. Das Array ist 10 Zellen
groß, also wenn alle 10 Zellen berücksichtigt.
Und dann ist Null natürlich der kleinste Wert,
weil der zum Beispiel in Zelle 4 steht oder in Zelle
5 oder in Zelle
Jetzt klar geworden. Gut, das Ganze kann man
auch mit der Alternative, mit der neuen Vorschleife machen.
Genauso hier, da sitzt ein bisschen knapper aus.
Also wenn man nur so ein Minimum ermitteln will,
dann ist das tatsächlich ein bisschen hübscher, das so hinzuschreiben.
Also mit dieser etwas länglichen Schreibweise, mit diesen, mit der normalen Vorschleife.
Verschiedene Möglichkeiten, ihr müsst euch damit vertraut machen,
ihr müsst es üben, ihr müsst es einfach machen.
Das ist das, was beim Programmieren ganz wichtig ist.
Gut, dann haben wir Zuweisung mit Arrays. Wenn ihr verstanden habt,
dass eine Ray-Variable nur eine Referenz variable ist,
dann ist es klar,
wenn ich sowas zuweise,
dass ich dann auch
nur die Referenz kopiere
Beispiel, ich deklariere einen Interrail 1,
ich italisiere das gleich mit einem Arrailer Größe 3 und schreibe anschließend in Arrail 2,
das ich hier neu deklariere und weise dem gleich mal in Arrail 1 zu.
Dann ist das eine Kopie der Referenz. Beide Referenzen verweisen
dann auf dasselbe Arrail-Objekt. Also Interrail 1 und Interrail 2
verweisen beide auf dieses Objekt. Wenn ich tatsächlich das Arrail-Objekt kopieren will,
dann muss ich, gibt es zwei Möglichkeiten mindestens,
ich kann einfach elementweise in ein neues Arrail-Objekt reinkopieren.
Also ich kopiere wirklich dieses Arrail-Objekt, dieses Objekt hier irgendwie
Ja. Lege ein neues Array-Objekt an mit der gleichen Größe
und kopiere da die ganzen Werte rein.
Oder ich benutze Klum. Klon ist für Array ist nämlich tatsächlich implementiert.
Gucken wir uns das mal an, kopieren von Array-Objekten.
Die erste Möglichkeit ist, ich erzeuge ein neues Array-Objekt,
also einen neuen Behälter und kopiere elementweise.
Also hier Int-Array ist dieses eine Array-Objekt,
was hier automatisch implizit erzeugt wird durch diese Initialisierung.
Hier schreibe ich jetzt einfach New Int und dann benutze ich
die Größe des ersten Arrays,
um einen gleichgroßen Ray-Behälter zu erzeugen
Und dann mache ich eine Schleife,
indem ich durch alle Elemente des ersten Arrays durchgehe und speichere
die Werte aus dem ersten Array in das zweite Array rein.
Das ist das, was hier passiert. Das ist sehr zu Fuß
. Etwas knapper geht's mit Clone. Also die Operation Clone
kann ich hier einfach verwenden, kann ich was sagen.
Hier soll ein Array-Objekt geklont werden. Und dann werden auch
die Inhalte mitgeklont. Also in diesem Fall ist es dann so,
ich habe ja ein Interray und die Belegungen der Zellen
werden genauso übernommen.
Dann habe ich tatsächlich
zwei Referenzen auf zwei Array-Objekte
Okay. Zwei dimensionale Arrays gucken wir uns jetzt noch nicht an.
Erstmal bis zu diesem Punkt gibt es noch Fragen zu den Arrays.
Da ist eine Frage. Wenn ich jetzt in Array mal in
unserer Ferenzen drin bin und ich rufe die Operation Klot auf,
werden dann wieder Geld konzentriert oder werden dann auch neue Objekte aufgegeben?
Ah, eine sehr gute Frage. Ich habe gerade gesagt,
man kann die Operation Clone verwenden und er sagte, er fragte,
was ist denn, wenn jetzt in den Zellen des Arrays Referenzen stehen.
Also wenn ich als Elementtyp einen Objekttyp habe, einen Referenztyp,
werden dann nur die Referenzen kopiert oder werden auch die Objekte,
die da drin stehen, mitgeklont. Und ganz wichtig,
die werden nicht mitgeklont, weil in Java gibt es keine Garantie,
dass es für jeden Objekttyp die Operation Clone gibt. Die Arey-Objekte,
die können das, die kann man klonen, aber das,
was da drin steckt, also wenn da Referenzen drin stecken,
die Objekte lassen sich allgemein,
es lassen sich allgemein nicht alle Objekte in Java klonen,
also kann man das,
kann man nicht davon ausgehen,
dass die Objekte
dann wirklich geklont werden
Es werden nur die Referenzen, die in den Zellen drinstehen,
die werden kopiert. Sonst noch eine Frage zu Arrays.
Das ist nicht der Fall. Okay, dann wunderbar.
Dann haben sie das jetzt noch relativ früh, zwei Minuten vor drei.
Dann kann ich hier noch mal ein kleines Projekt zeigen.
Mandelbrot, Mario Kart. Großer Favorit bei unseren Betreuern.
Sehr cooles Projekt. Aber leider auch so ein bisschen Zu viel Generiertes drin.
Das könnt ihr euch jetzt in Ruhe auf der Zunge zergehen lassen.
Das sind jetzt fünf Minuten Pause. Die haben sich wirklich richtig
Mühe gegeben. Das ist ein Riesenteil, also wirklich cool.
Es sollte ein Spiel werden, aber haben sie dann aber
doch gelassen. In die Mitte rücken, ah ja,
okay, das ist aber nicht so.
Jetzt ist es nur eine Animation geworden, dieses Spiel.
Ihr könnt ihre Werbung stehen, nur ein Nur ein paar Beschreibungen,
das Prinzip und so weiter. Also es ist wirklich toll,
mit Schrift hier und das ist der Spieler, den man bewegen soll.
Er muss Hindernissen ausweichen. Und man hat irgendwie drei Versuche
, so eine Spielbeschreibung. Und dann noch eins.
Viel Spaß, Herr Fun. Und dann wird hier jetzt
richtig was animiert. Ich tue nichts. Also nicht,
dass ihr glaubt, ich spiele das jetzt hier.
Das ist, wie gesagt, nur eine Animation.
Aber ich finde das schon, also die haben wirklich
viel Arbeit da reingesteckt,
das zu machen
Das ist schon ziemlich nett hier,
wenn noch Punkte aufgesammelt, wenn man irgendwas einsammelt da,
wenn man nicht gerade gegen diese Wände fährt.
Ja, dann wird das noch so ein bisschen farblich abgewandelt
da oben. Ja. Großes Kino. Wie gesagt,
das geht eine Weile, deswegen habe ich es jetzt in
die Pause gelegt
Oh, das ist das Thema.
Tja, alles ausprogrammiert. Irgendwann ist es auch gleich
mal zu Ende
Das wird mein Rechner gerade langsam hier,
habe ich das Gefühl. Da. So,
jetzt gibt es nochmal einen kleinen Epilog,
Game Over,
Highscores,
werden hier aufgeführt
Ja. Genau. Nochmal Werbung jetzt und dann wird dir noch
ein Countdown runtergezählt. Also die haben wirklich mit ganz viel
Energie da ziemlich viel gebaut. Das ist schon sensationell,
aber wie gesagt, es konnte dann leider nicht gewinnen,
aber erstmal denke ich, einen Applaus für dieses wunderbare Projekt.
Jetzt geht es von vorne los, also jetzt muss man
es abbrechen.
Gut, sehr schön, ja, die Zeit ist schon fast rum.
Wollt ihr noch mehr? Ja, es gibt ja noch die Gewinner nachher.
So, aber die Pause ist jetzt vorbei, ne?
So. Naja, das war jetzt fünf Minuten Pause,
also wer jetzt gehen muss, der muss dann einfach gehen.
Ja, leider. Okay. Die kommen am Ende.
Die Gewinner werden noch gezeigt,
keine Angst
Ah, wir hatten tolle Einreichung. Wir hatten auch wieder
eine Nürncat, die ich letztes Mal schon gezeigt hatte.
Diese fliegende Katze mit dem Schweif ohne Musik.
Tolle Sachen. Gut. Lass uns noch mal jetzt hier
so ein bisschen den Stoff abarbeiten.
Ihr wollt ja auch, ihr sollt ja auch was lernen.
Und dann können wir uns noch mal die Gewinne angucken.
Da gibt es auch eine Preisverleihung. Ich habe hier
tolles Niederecker-Marzipan für die Gewinner. Ich hoffe,
die sind dann auch da, die Gewinner.
Das wäre ganz schön. Gut. Jetzt geht es um
zweidimensionale Arrays
Wenn ihr jetzt gefunden habt, dass The Race schon ziemlich kompliziert waren,
so mit Objekten und Referenzen und so weiter, jetzt wird es richtig kompliziert,
weil zweidimensionale Arrays sind tatsächlich in Java Arrays von Arrays.
Das heißt, so ein zweidimensionales Array,
was man sich ja relativ gut vorstellen kann,
abstrakt als so eine Matrix, wo ich sage,
hier habe ich eine variable A,
die zeigt auf dieses Array, auf dieses zweidimensionale Array,
dann kann ich mit A31 direkt auf diese Position zugreifen.
Auf diese Zelle in dem zweidimensionalen Array. Aber als Modell,
was im Speicher passiert, müsst ihr eher das im Kopf
haben.
Ihr habt eine Referenzvariable
Ray-Varianten sind immer Referenzvariablen. Die verweist auf ein Array-Objekt.
Und dieses Array-Objekt enthält jetzt Referenzen auf Arrays.
Also diese Array-Referenz ist vom Typ zweitmensionales Array.
Und in den Zellen sind dann eindimensionale Arrays.
Das ist so ein bisschen das Prinzip, wie es aus
diesem Tic-Tac-Toke kennengelernt habt, mit den Zeilen und Zellen.
Also das ist tatsächlich mehr oder mehr die gleiche Struktur,
die bei Arrays wirklich dahinter steht.
Ein konkretes Beispiel ist hier vier gewinnt. Und da können
wir uns jetzt hier nochmal So ein Vier gewinnt angucken.
Machen wir mal was auf hier, Vier gewinnt.
Da habe ich hier tatsächlich einen Vier gewinnt und kann mir hier mal so eine Gummi machen.
Und jetzt können wir zum Beispiel, weil mir wird ja nachgesagt,
dass ich in meiner Vorlesung immer schummeln würde,
wenn ich gegen das Publikum spiele, bei Tic-Tac-Toe oder so.
Deswegen können wir jetzt hier ganz fair gegeneinander vier Gewinn spielen.
Ihr kennt wahrscheinlich viel gewinnt. Also hier auf der Folie
ist es angedeutet. Das ist das Gleiche wie beim letzten Mal.
Das kenne ich schon. Das ist so ein Vier-Gewinn-Spielfeld.
Da schmeißt man so Chips rein und die fallen dann
immer so weit runter,
wie es geht
Das heißt also, und da muss man versuchen,
viel in eine Reihe zu kriegen und den Gegner davon abzuhalten,
auch viel in eine Reihe zu bekommen.
So, und wenn wir das jetzt hier spielen,
dann kann ich jetzt mal anfangen,
ich tippe jetzt mal auf diese Reihe.
Hier, zack, und dann fällt der da so runter.
So, jetzt könnt ihr sagen, wo ich hinsetzen soll.
Links daneben, links daneben, okay, hier soll einer hin.
Dann setze ich mal hier einen hin. Wo soll ich
hinsetzen? Obendrauf, obendrauf. Hier so, okay.
Ja, dann setze ich hier mal einen hin.
Soll ich hin
Ja. Ich höre nichts. Ganz links außen. Ganz
links oh ja, okay, wenn ihr das wollt.
Okay, dann setze ich mal hier einen hin.
Rechts daneben, hier. Ja, okay.
Dann setze ich hier mal einen hin. So, hier
einen drauf. Ja. Hier. Hier
Hier. Ja, okay. Habe ich gewonnen. Irgendwie,
irgendwie bin ich zu gut in diesem Spiel, wirklich.
Also faszinierend. Gut, aber das ist genauso ein Beispiel,
das Interface Spielfeld ist hier relativ einfach wieder.
Irgendwie ein bisschen komplizierter ist es,
weil man da so diese Zellen besetzen kann.
Da sieht man dann hier, irgendwie entferne obersten Spielsteinen,
gibt Besitzer, Spalte ist frei und so weiter.
Da gibt es ein bisschen komplizierter. Aber das Spielfeld Array
ist dann tatsächlich hier implementiert als,
oh,
Spalten und Zeilen
Ist das überhaupt ein zweidimensionales Array? Ist es gar nicht
. Spalte, Zeilen, oh, falsches Beispiel hier.
Gut, ich wollte eigentlich zeigen, wie das mit einem
zweidimensionalen Array aussieht. Scheint jetzt gerade nicht zu klappen.
Aber wir gucken uns hier ja gleich jetzt nochmal genauer an.
Also, wir haben ein zweidimensionales Array, deklarieren wir,
indem wir einfach zweimal diese Dimensionsklammern angeben. Also ein,
Klammer, paar eckig, es steht für eine Dimension.
Also, wenn ich zwei angebe, habe ich einen Zweidimension,
also ich kann auch mehr Dimension Dimensionen angeben,
aber fangen wir erstmal mit zwei an
Dann kann ich tatsächlich das so schreiben,
dass ich zuerst eindimensionales Ray-Objekt erzeuge, also New-Ind 5,
also die erste Dimension mit fünf Zellen.
Und die zweite Dimension gebe ich erst mal nicht an.
Und dann mache ich einfach, gehe ich durch alle Zellen durch.
Also in AI weise ich dann eine Referenz zu auf ein
neues Interray. Dann wird das hier so gemacht.
Man kann auch einfach schreiben, New-Ind 5.4. Dann habe ich
ein zweidimensionales Array.
Das geht ganz wunderbar
Wenn ich jetzt auf so ein zweidimensionales Array zugreifen will,
dann kann ich das genauso machen, wie bisher auch für eindimensional.
Ich sage einfach, gebe Roe und Cullim an,
also sozusagen den Index, auf den ich zugreifen will.
Ich kann das eben halt für alle machen.
Ich gehe also hier durch die Reihen durch und durch
die Spalten und kann dann tatsächlich in jede Zeile,
in jede Zelle des zweidimensionalen Arrays einen Wert reinschreiben.
Diese Initializer, die wir gesehen haben,
also wenn ich eine Array-Ray-Variable deklariere,
kann ich ja direkt mit so einem Initializer die Inhalte schon belegen.
Und das kann ich tatsächlich auch so geschachtelt machen,
also für zweidimensionale Arrays
Sieht man auch schön, dass man
sozusagen eindimensionale Arrays in die Zellen des ersten Race hineinschreibt.
Das kann man tatsächlich so hinschreiben. Faszinierend, aber
es geht. Jetzt ist es ein bisschen hakeliger,
wenn man sowas jetzt kopieren will. Also ich möchte tatsächlich,
ich habe so ein zweidimensionales Arrail, möchte das kopieren,
geht es eigentlich von Hand im Prinzip genauso wie bei den Eindimensionalen.
Ich kann das von Hand machen oder ich benutze wieder Clone,
aber da muss ich halt wieder aufpassen.
Dieses Clone ist nicht rekursiv definiert. Also eben schon so ein bisschen wie die Frage,
was ist denn, wenn da Referenzen drinstehen und bei einem
zweidimensionalen Array steht ja in der ersten Dimension,
stehen ja Referenzen auf die zweite Dimension
Dann werden die halt auch nicht mitgeklont. Das heißt,
wenn eine vollständige Kopie gewünscht ist,
dann muss ich wirklich von Hand alle Dimensionen kloppen.
So, und jetzt wird es langsam wirklich kompliziert.
Da muss man also wirklich sagen, wenn man an dieser Stelle
Referenzen in Java nicht kennt, dann ist man verloren.
Ohne Referenzen ist das nicht mehr nachvollziehbar. Gut.
Gibt es jetzt noch Fragen zu zweidimensionalen Arrays noch möglicherweise?
Ist, wie gesagt, nur einfach eine Indirektion mehr.
Also wenn ihr jetzt ein zweidimensionales Array habt von Elementyp Referenz auf Person,
dann habt ihr wirklich so ein Geflecht von Objekten,
die auf Objekte verweisen und so weiter.
Ganz wild. Aber alles straightforward, logisch, konsequent.
Wenn man es einmal verstanden hat, ist es ganz einfach.
Wenn man es nicht verstanden hat, ist es schwierig,
gerade mit den Referenzen.
Gut. Was sind jetzt die Vorteile von Arrays?
Wir haben jetzt dieses Zeug gesehen. Ihr habt gesehen,
das ist eine relativ eigenartige Syntax mit diesen eckigen Klammern.
Die sind also sehr speziell unterstützt. Die haben,
als die Java konzipiert haben, gesagt,
wir müssen auch Rays anbieten, die gehören einfach dazu.
Es gibt so nicht ganz ernst gemeinte Zitate,
die einzige gottgegebene Datenstruktur ist das Array
Also ein Ausschnitt aus dem Speicher,
das ist das Natürlichste, was man so haben kann.
Und da möchte man dann auch sehr schnell drauf zugreifen können.
Das ist das eine. Der Indexzugriff kann sehr schnell abgebildet
werden. Das ist etwas, was ganz wichtig ist.
Das geht auf den meisten Rechenarchitekturen tatsächlich schnell in einem Segment,
in einem Speichersegment, indiziert zuzugreifen.
Und auch das Kopieren eines ganzen Arrays ist relativ effizient.
Ich kann tatsächlich ja auch eine Kopieroperation der unterliegenden Architektur benutzen.
Und die Arrays haben in Java auch den netten Vorteil gegenüber
den Listen und den Mengen, Dass sie auch elementare Typen zulassen.
Letzte Woche haben wir ja gesehen,
wenn man so Int oder Bulien in so einer Menge drin haben will,
dann musste man da diese komischen Rapper-Objekte benutzen.
Die waren relativ hässlich. Race and Drama sind da straightforward
. Ich kann tatsächlich als Elementtyp die primitiven Typen wählen.
Genauso wie ein Referenztyp. Die Nachteile, ja,
das ist klar, wenn wir in Java zwar erst zur Laufzeit festlegen,
wie groß das Race,
dann ist das flexibler als in Pascal,
wo man es tatsächlich schon im Programm
Code festlegen muss
Aber sobald ein Objekt erzeugt ist, behält es seine Größe.
Ihr könnt ein Array nicht vergrößern. Das ist ein Stück
Speicher, was irgendwie aus dem Hieb rausgeschnitten ist.
Und wenn ihr da jetzt irgendwie mehr Speicher wollt,
dann könnt ihr nicht einfach da vergrößern.
Das geht nicht. Da könnte ja was anderes liegen.
Das ist nicht unbedingt ein Nachteil, wenn man keine dynamischen Listen braucht.
Spielfelder sind das klassische Beispiel. Wir sind nicht dynamisch,
dann kann man es einfach statisch machen.
Wunderbar. Okay. Außerdem ist es so,
wenn ihr jetzt sowas habt, wie ein Array mit Elementen
drin und ihr wollt Beispiel an die dritte Position etwas dazwischen schieben.
Ihr wollt wirklich jetzt,
ihr habt zwei Elemente dann und dahinter noch weitere Elemente,
ihr wollt jetzt da was reinfügen und alle Elemente danach sollen sich verschieben.
Etwas, was ihr bei den Listen letzte Woche gesehen habt,
was da total komfortabel geht.
Das geht auf Arrays nicht. Da müsst ihr von Hand
wirklich in den Zellen alles ein bisschen weiterschieben.
Und ihr müsst darauf aufpassen, dass dann das Array nicht
irgendwie zu klein ist und man da gar keinen Platz mehr hat.
Das ist relativ kompliziert. Also die ganzen höherwertigen Operationen,
die man so auf Sammlung gerne hat,
in bestimmten Anwendungsfällen,
die sind da nicht mit dabei
Okay, also, Größe nicht veränderbar. Ein Array modelliert
zusammenhängende Speicherzellen, verschieben von Hand. Insgesamt ist es einfach so,
ihr könnt euch das so vorstellen, wenn hier der Speicher ist,
dann sind die Arrays da so drüber, eine Abstraktionsebene drüber.
Der Speicher ist ungetypt. Bei I Marray ist es immerhin so,
die Zellen haben ja einen Typ, also der Elementtyp ist ja festgelegt.
Und da drüber liegen eigentlich so ein bisschen halb daneben,
liegen dann diese wunderbaren Sammlungstypen im Collections Framework,
die man, und wenn ihr jetzt irgendwie Anwendungen schreibt,
dann greift ihr meistens auf die zu.
Manchmal greift ihr aber auch direkt auf das Array zu.
Und wir werden uns auch in den nächsten Wochen ansehen,
dass diese Sammlung hier mit diesen Arrays auch implementiert sind
Gut, das ist eigentlich schon alles das,
was ich heute erzählen wollte, zu Rave.
Eine Ray elementare, imperative Datenstruktur, in allen imperativen Sprachen,
gibt es so etwas wie eine Array?
Sehr speichernah konzipiert. Geordnete Reihe und gleichartige Elemente über den Index
. Niedriges Abstraktionsniveau, Elementtyp und so weiter. Gut,
nochmal eine kleinere Storesi-Frage hier, damit es ein bisschen locker wird.
Ich starte mal schon mal die Abstimmung.
Welche der folgenden Aussagen zu diesem Java-Quelltext
ist richtig
Also wir haben hier irgendwie eine Referenzvariable, eine Array-Variable,
die wird igitalisiert, dann wird hier irgendwie auf die Länge
zugegriffen und es wird auf eine Zelle zugegriffen.
So, jetzt stehen hier vier Aussagen und nur eine von diesen Aussagen ist richtig.
Also Aussage A ist der Wertevariablen Lenn nach Ausführung dieser Anweisung
, ist fünf. Aussage B,
in der ersten Zeile wird ein Array-Objekt für drei Int-Werte angelegt,
Aussage C, der Wert der Variablen I,
nach Ausführung dieser Anweisung ist drei und Aussage D,
der größte zulässige Index für Zugriffe auf die Elemente von Interray
ist drei
Nachdem ihr jetzt von mir hier das
in aller Ausführlichkeit vorgekaut bekommen habt, denke ich mal,
solltet ihr diese Frage auch ganz gut beantworten können?
Gut, wir haben
schon 75 Stunden zusammen
Das ist auch keine Fangfrage. Ich habe auch schon
zu Race, kann man wunderbare Fangfragen stellen.
Die heben wir uns dann für die Klausur auf.
Witzig. Okay. Ja, 115 Stimmen, wunderbar.
Wir gucken mal auf eure Verteilung. Okay, 80 Prozent sagen,
ja, der größte zusätzliche Index für Zugriffe ist,
und das ist natürlich auch die richtige Aussage.
Wunderbar, ja, 80 Prozent haben das richtig,
dann bin ich glücklich.
Gibt es jetzt noch Fragen zu Race
Also jetzt nochmal bezogen auf das Beispiel,
was ich hier in der Aufgabe hatte oder soll ich nochmal
so ein zweidimensionales Array hier live vorführen oder das kopieren oder?
Ich glaube, das könnt ihr auch alles in den Übungen trainieren.
Zweidimensional mal vorführen. Ah, cool, das machen wir mal.
Jetzt wird es haarig. Jetzt wird es wild. Okay,
nehmen wir mal hier, ich mache mal ein zweidimensionales Int-Array.
Ja, sind Array 2 dimensional und sage,
das sei mal
New Int-Array
5 und 4. So, das kann ich ja so hinschreiben.
Dann habe ich hier mein Int-Array 2. Habe also jetzt
eine Referenz auf ein, zweidimensionales Array.
Die kann ich mir mal rüberziehen. Nehme ich jetzt lieber
mal Int-Array 2, damit es keine Verwirrung gibt.
So. Objektinspektor zeigt mir die erste Referenz geht auf einen Behälter,
auf einen Array-Behälter,
der enthält
überraschend fünf Referenzen
Wenn ich das jetzt hier mir angucke,
dann kann ich tatsächlich hier die ganzen Dimensionen mir anzeigen lassen.
Das heißt, ich sehe jetzt quasi hier mein Objektdiagramm für
mein zweidimensionales Array. Da steht natürlich jetzt überall null drin.
Und die Größe steht hier auch immer dabei.
Die Länge ist ja hiermit abgelegt. So,
jetzt kann ich mir auch zum Beispiel von Interray mal,
Interray 2.längs,
kann ich ja
einfach aufrufen
Ist fünf. Enthält ja fünf Zeilen. Da ist eine
Frage. Könnte man das auch so schreiben? Klar,
das ist in der, keine Ahnung, dritten Zeit oder so.
Vier Spalten, nee, die Freude.
Aha, spannende Frage. Er fragt, ob man jetzt
das nicht auch sozusagen asymmetrisch machen könnte.
Also ich habe ja jetzt hier in dem ersten Array,
habe ich einfach nur Referenzen auf Arrays.
Und das ist genau eine ganz clevere Frage,
weil ich kann jetzt hier eine Referenz haben auf ein In-Array der Länge
4. Und in der nächsten Zeile könnte ich
eine Referenz haben auf ein Interrated Länge
Das ist durchaus möglich. Der Typ muss nur richtig sein.
Also das ist ein Ray von Int-Arrays und wie lange die Einzelnen sind, ist egal.
Ich kann tatsächlich jetzt mir hier, kann ich ja mal machen,
ich mache mir mal einen Int-Array, ein eindimensionales Int-Array.
Int-Array, da sage ich jetzt mal,
das ist New Int, machen wir mal irgendwas Großes.
Acht, ja, richtig groß. So, dieses Interray
habe ich. Und jetzt kann ich diese Referenz,
kann ich jetzt meinem Interray 2 zuweisen,
ich kann also sagen, Int-Array 2 an der Position
Zwei soll genau diese Referenz bekommen in Array. Jetzt speichere
ich sozusagen dieses etwas größere, eindimensional, die Referenz,
darauf speichere ich in diesem zweidimensionalen Array in die entsprechende Zelle.
So, und jetzt müsste tatsächlich in diesem Beispiel hier,
hier an der Stelle zwei,
müsste jetzt eigentlich der Objektinspektor aufpoppen für ein größeres Array,
wenn das geklappt hat.
Und siehe da, ist es tatsächlich so.
Da ist jetzt ein längeres Ding drin. Vom Typ ist
alles in Ordnung. Es ist ein Array von ins.
Das heißt, ihr könnt tatsächlich in so einem zweidimensionalen Array
unterschiedlich lange Zeilen in den Zellen haben
Da ist noch eine Frage. Muss man das denn
mit einem fein dimensionalen Airbag dazu verbinden oder kann man gleich
in eine zwei dimensionale Airbag, vielleicht was zu sagen?
Nee, der Typ ist,
der Element-Typ in dem ersten Array hier ist,
das ist eine Referenz auf ein eindimensionales Array.
Da müssen eindimensionale Arrays drin sein. Du kannst ja nicht
ein zweitdimensionales Array reinschreiben. Genau. Und wenn ich jetzt
zum Beispiel hier mal was mache,
ich sage jetzt in zweidimensional in Array-Kopie,
ist gleich in Array zweidimensional.clone
Jetzt klone ich hier diese erste Dimension von dem zweidimensionalen Array.
So, da habe ich also jetzt mal ein Int-Array K.
Das ist eine Objektreferenz. Kann ich mich ja auch rüberziehen.
Int K, so egal, anderer Name. Jetzt habe ich hier
dieses Int K. Und hier habe ich das andere Ding.
So, das sind jetzt, die sind gleich.
Die Objekte, diese Referenzbehälter hier sind gleich.
Aber das, worauf sie verweisen, ist dasselbe.
Also wenn ich jetzt zum Beispiel hier draufklicke,
kommt der Objektinspektor da
Und wenn ich das wieder nach hinten hole und wieder mir
den hier nach vorne hole und dann diesen nach vorne hole.
Ganz schön zickig, aber egal, wenn ich jetzt
hier draufklicke, dann ist das der gleiche Objektinspektor.
Also es wird wieder der da oben kommen.
Also die zeigen dann wieder öfters Gemeinsame. Gut, sehr schön.
Da haben wir noch mal so ein bisschen was hier live gemacht.
Das ist noch eine Frage. Eine Eine Integration, die
kurze Befugung ausbildet. Ob man an einem Interrail die Equals-Methode
ausführen kann. Sehr gute Frage. Ich habe ja gesagt,
die Race sind Objekte. Und wir wissen ja,
in Java ist alles ein Objekt,
was nicht gerade ein primitiver Typ ist
Also würde ich ja erwarten, dass ich zum Beispiel auf Int-Array K,
einfach jetzt aufrufen kann, E-Quills, Int-Array 2.
Und siehe da, das ist tatsächlich Fords.
Aber ich kann es aufrufen. Also das ist das ganz
Wichtige. Ihr könnt an einem Ray alle Operationen aufrufen,
die man auf jedem Objekt aufrufen kann.
Ihr könnt also auch Hashcode aufrufen. Ich kann auch jetzt
hier Int-Array 2.hashcode aufrufen. Dann kommt irgendein Hashcode da raus
. Also alles, was man mit Objekten machen kann,
kann ich mit Arrays
auch machen
Ich kann sie mit Equals vergleichen, aber die Arrays machen keinen Inhaltsvergleich.
Das heißt also, in diesem Fall waren es einfach verschiedene
Objekte und deswegen sind sie, kamen da als Ergebnis Fonds raus.
Noch eine Frage. Zu dem Punkt,
wenn ich jetzt die Interrap 2 an schneller eins,
also innerhalb der Rays, dass die Equals,
die Interrap Car, Anstellerei ist, machen würde,
dann müsste das, dass das nicht gleich sein kann.
Okay, also er fragt,
wenn ich jetzt von diesen beiden ersten Dimensionen Arrays,
also ich habe ja hier zwei Dinge, einmal diesen,
Und einmal diesen, der jetzt beide nicht gleichzeitig vorne stehen wollen.
Und ich glaube, ich habe das so verstanden,
wenn jetzt ich das erste hier vergleiche mit dem ersten da,
ob die dann gleich sind.
Ja, das können wir mal machen. Machen wir mal Int-Array,
K, 1, Moment K, 1, ja,
Punkt equels, Int-Array 2, nee, Int-Array,
doch, Int-Rate 2 heißt das Ding, ne?
Int-Array 2 und da möchte ich auch den ersten haben
Die müssten jetzt gleich sein,
weil sie auf dasselbe Objekt verweisen, sind die Referenzen gleich.
Da würde ich jetzt einen Schuh erwarten. Und da kommt
auch Tour raus. Hammer. Wahnsinn. Gut, jetzt
ist Schluss hier. Jetzt muss ich weitermachen. Sehr viel
live gezeigt. Das macht mir immer besonders viel Spaß.
Kommen wir jetzt noch mal schnell zu einem anderen Thema,
damit wir auch noch ein bisschen am Ende noch hier Siegerehrung machen können.
Ihr habt bis jetzt Klassen- und Objekte kennengelernt, ganz straight forward.
Ihr habt gelernt, eine Klasse ist sowas wie eine Schablone.
Eine Klassendefinition ist der Quelltext einer Klasse
Mit so einer Klasse, mit so einer Klasse kann ich
mir Exemplare erzeugen. Also Klassen sind,
die Einheiten des statischen Programmtextes und Objekte sind so das Dynamische.
Wenn ein Programm läuft, dann sind da ganz viele Objekte.
Alle Operationen beziehen sich immer auf ein Objekt und so weiter.
Jetzt ist es aber so, dass in Java zum Beispiel
die Klassen selber auch zur Laufzeit irgendwie existieren.
Man kann das auch schon so ein bisschen sich vorstellen,
wenn ich mir hier sowas angucke, wie hier vier gewinnt,
dann kann ich ja hier an diesem Objekt,
das ist ja sehr objektorientiert,
Blue J.,
ich habe ja hier meine Exemplare und an denen
kann ich ja üblicherweise
Operationen aufrufen
Und man kann ja quasi das konzeptuell auch so sehen,
naja, das, was man an so einem Klassending
hier aufrufen kann, das ist zum Beispiel ein Konstruktor.
Das ist so eine Operation, die das Klassenobjekt anbietet.
So kann man das konzeptuell sehen. Aber man kann tatsächlich
noch mehr solche Dinge definieren. Man kann tatsächlich diese Dinge
als eigene Objekte ansehen und da auch dann Operationen definieren.
Und das ist ganz spannend, wie das in Java gemacht ist.
Und das sollten wir uns mal ansehen.
Also Klassen sind in Java auch selbst Objekte. Das heißt,
was ihr machen könnt, ist,
ihr könnt für ein solches Klassenobjekt
auch einen Zustand definieren
Genauso wie er bei einem Exemplar ja festlegen könnte,
dass jedes Exemplar eine Exemplarvariable haben soll,
könnte für die ganze Klasse sagen, diese Klasse hat eine Zustandsvariable.
Und zwar macht man das mit dem Schlüsselwort Static. Das heißt,
wenn ich in der Klasse Konto sowas mache wie Private Static
in Exemplarzähler, dann wird damit eine Klassenvariable deklariert.
Wenn da jetzt das Static nicht stünde, wäre es eine Exemplarvariable.
Und jedes Exemplar hätte dann ein Feld von diesem Typ.
Aber hier ist es jetzt so,
hier wird das Ding nur einmal angelegt,
nämlich genau in dem Klassenobjekt von Konto
Und hier als Beispiel, wenn man sowas benutzen kann,
ist einfach mal gesagt, ich möchte für meine Klasse die Exemplare zählen.
Ich möchte sozusagen zur Laufzeit immer fragen können,
wie viele Exemplare sind denn schon erzeugt worden?
Und das mache ich ganz einfach, indem ich im Konstruktor diesen Exemplarzähler,
den ich hier deklariert habe, immer erhöhe, Exemplar zähle erhöhen.
Das heißt, jedes Mal,
wenn ich ein neues Konto anlege, wird dieser Exemplarzähler erhöhen.
Dann kann ich tatsächlich diesen Zähler auch abfragen.
Der ist jetzt hier privat deklariert, also sehr ähnlich,
wie wir es bei Exemplaren auch haben wollen.
Die Felder sind privat und dann kann ich einem Klienten über eine Methode Zugriff gewährleisten.
Und das ist hier eine Klassenmethode. Wenn da ein Static davor steht,
dann ist es eine Klassenmethode, sonst ist es eine Exemplarmethode.
Anzahl erzeugt der Exemplare, dann kann ich also das Klassenobjekt jetzt fragen,
hey, sag mal, wie viele Exemplare sind denn schon erzeugt worden?
Und das lässt sich ganz einfach aufrufen an dem Kontoobjekt selbst.
Und wie benenne ich das Kontoobjekt nahe mit dem Klassennamen? Also hier,
wenn ich irgendeinen Klienten habe, der Klasse Konto,
ein Kontovorwalter oder was weiß ich was,
der hat jetzt hier eine Methode Status prüfen,
dann steht irgendwelches Zeug drin und dann sagt er hier,
naja,
Anzahl Konten ist gleich Konto.
Das ist der Name des Klassenobjektes.
Punkt, Anzahl erzeugter Exemplare
Und dann kriege ich da meinen Wert raus.
Also es ist so eine Art Meta-Ebene, die man hat.
Man hat die Klasse und die ganzen Exemplare.
Und dieses Ding, dieses Objekt, was die Klasse repräsentiert,
gibt es auch zur Laufzeit in einem Java-System.
Und ich kann dem sogar einen Zustand geben und ich kann da
auch mit interagieren, kann da Methoden aufwurfen und Englisch ist.
Sehr häufig ist es so, dass man bei den Klassen
aber gar keinen Zustand haben will.
Es gibt auch so Klassenoperationen, die rein als Dienstleistung modelliert sind.
Also zum Beispiel in Java Lang Marth. Da gibt es einige statische Operationen, die man aufrufen kann. Ich kann das hier mal live zeigen,
also ich kann hier schreiben, Marth.pow, das ist eine Klassenmethode,
die ich jetzt aufrufe, also an dem Klassenobjekt Marth,
da rufe ich jetzt mal auf 2,10,
das ist Power, also two two the power of 10,
also 2 hoch 10 und da wisst ihr alle, was da rauskommt,
ja, das ist eine der Magic Numbers in der Informatik,
das ist
die 1024. Und dann kommt hier als Ergebnis ein Double raus,
weil Marth eben mit Double Wertner rechnet
Kann ich also einfach so hinschreiben. Es gibt noch ein
anderes Beispiel. Die klasse Intager, die kennt ihr.
Das war diese komische Rapper-Klasse, wo man sich Exemplare erzeugen konnte,
um ein Int einzuwickeln in ein Inteager-Objekt,
damit man dieses Inteager-Objekt in eine Sammlung reinfügen konnte.
Aber die haben noch ein bisschen mehr angeboten.
Die haben zum Beispiel hier ein Pares Int.
Und dann kann ich jetzt hier einen String angeben.
Also Parsen ist immer eine Zeichenkette und aus der Zeichenkette
etwas Parsen heißt irgendwie etwas erkennen.
Also zum Beispiel 1, 2, 3. Die Zeichenkette 1,
2, 3 möchte ich jetzt umwandeln in ein Inteager
Da gibt es einfach Indiger Pass Int, zack,
kommt 1, 2, 3 raus.
Das ist jetzt sehr überraschend, ja. Aber ich kann
natürlich jetzt hier auch mal zeigen, was dann schiefgeht,
wenn ich hier jetzt irgendwie ein A reinschreibe,
dann ist das keine Zahl.
Das heißt, es wird versucht aus einer Zeichendarstellung,
aus einem String, eine Zahl umzuwandeln.
Das geht natürlich nur, wenn das nur Ziffern sind.
Wenn da jetzt so was drinsteht wie ein A,
da gibt es eine Acception. Number formed educception gibt es
da. Also das sind so Beispiele von so Klassenmethoden.
Da gibt es noch mehr davon. Zum Beispiel
die Klasse Arace in dem Paket Java You Till.
Die bietet so Convenience-Methoden an für den Umgang mit Arace.
Könnt ihr euch alles in Ruhe mal angucken in der API
Kann man zum Beispiel auch dann hier Klassenoperationen, Array,
Copy, gibt es auch in Java Lang System,
die kann man sich da durchaus auch angucken.
Gut, dann kommen wir jetzt zu einem Punkt, zu dem normalerweise,
wenn man irgendwie Java-Veranstaltungen hat, man gleich zu Anfang kommen muss.
Also so klassische Java-Veranstaltungen, die nicht Objects first vorgehen,
wie wir das hier in SNE1 machen,
die müssen als erstes mal erklären, so,
ihr startet eure Java-Programme, indem ihr Folgendes hinschreibt,
so Public Static Void, Mainz,
dringend Arcs, bla bla bla.
Das ist ganz fürchterlich, das ist sozusagen die Die dunkle Seite von Java,
naja, es ist ein bisschen vertrieben.
So schlimm ist es nicht. Eigentlich ist es ganz cool,
wenn man so eine Methode definiert, in einer Klasse,
eine solche statische Methode, dann kann ich die vom Betriebssystem aufrufen.
Das ist wirklich ganz nett. Das heißt also,
ich kann jetzt hier mal was zeigen.
Ich nehme mal hier CMD. Das ist eine Kommandokonsole.
Das ist was ganz Wildes. Jetzt gehen wir mal hier
runter in vier Gewinn war das, glaube ich.
Das ist hier das Verzeichnis, wo das vier gewinnt
Projekt drinsteht. Diese, diesen Pfad kopiere ich mir mal eben,
damit ich dann hier sagen kann, CD, Change Directory,
ja, da muss ich jetzt irgendwie sagen, einfügen,
so, dann stehe ich jetzt in diesem Verzeichnis vier Gewinner,
kann ich jetzt mit dir mir anzeigen lassen,
was da so alles drinsteht.
Und da steht jetzt unter anderem ja diese Klasse 4,
gewinnt Gui. Ja, 4 gewinnt Gui. Und wenn
jetzt in dieser 4 gewinnt Gui-Klasse eine Main-Methode drin wäre,
die, glaube ich, nicht drin ist,
ich hoffe mal nicht, nee, ist da nicht drin,
dann würde ich die jetzt aufrufen können.
Das heißt, ich könnte jetzt hier schreiben, Java,
4 gewinnt Gui. Zack, dann sagt der Fehler,
Hauptmethode in Klasse 4 gewinnt Gui nicht gefunden, Hauptmethode leider.
Das ist deutsch lokalisiert, das ist also unglaublich.
Eine wahnsinnig gute Fehlermeldung. Das heißt, wenn eine Klasse genau diese Methode anbietet,
dann kann ich die vom Betriebssystem aus auch rufen.
Das heißt, ich kann zum Beispiel mir ein Skript schreiben,
um dann so ein Java-Programm aufzurufen. Das heißt,
das ist quasi die Brücke zwischen Betriebssystem und dem Java,
der Java-Welt, die ihr kennt, mit den ganzen Objekten,
zu einer Main-Methode.
Wir können jetzt mal so eine Main-Methode schreiben,
hier in 4 gewinnt Gui
Schreib mir einfach mal so eine Main-Methode rein,
damit ihr seht, dass es wirklich funktioniert.
Public Static, Void, Main. Und das Schöne ist,
ihr könnt diese, diesen Kopf jetzt verstehen.
Ihr wisst jetzt, was da steht, ja.
String, aray, ist es ein String-Array.
So, dass man da als Parameter übergeben kann.
Und jetzt mache ich hier irgendwie nur das, was ich
hier auch machen würde, New, 4, gewinnt Gui.
Ich möchte also hier noch einfach so ein Exemplar erzeugen.
Das kann ich hoffentlich übersetzen, ja
Und jetzt müsste ich tatsächlich, weil jetzt diese Klasse,
diese Main-Methode hat, jetzt kann ich hier im Dings das aufrufen.
Java 4 gewinnt Gui. Und weil jetzt das eine Main-Methode ist,
also diese Einstiegsmöglichkeit da ist, wird jetzt hier tatsächlich das Ding gestartet.
Und schon kann ich mein Java-Programm aus dem Betriebssystem starten.
Cooles Zeug, das ist wichtig, wenn man verstehen will,
wie das in einem Betriebssystem eingebettet ist.
Ansonsten braucht man dieses blöde Main nicht zu kennen.
Und wir haben euch jetzt erst mal zehn Wochen damit verschont
und euch nicht ballert irgendwie zugemutet, irgendwas hinzuschreiben,
was ihr alles nicht verstehen könnt.
Inzwischen wisst ihr alles, ihr wisst, was Public ist,
was Static ist, was Volt ist.
Großartig. Toll
Voll. Ein weiteres Mysterium,
was ihr auch schon jetzt ein paar Mal gesehen habt,
ist so dieses berühmte System-Out-Printing,
wo man Aufgaben auf die Konsole machen kann.
Das ist jetzt auch ein bisschen besser erklärbar in dieser Klasse Java Lang System.
Da gibt es eine Klassenkonstante, die heißt Out.
Das ist einfach eine öffentliche Konstante. Und an dieser Konstante,
die ist vom Typ Prince Stream und an der kann ich
dann tatsächlich die Operation Printing aufrufen.
Könnt ihr euch mal in Ruhe angucken,
reicht die Zeit jetzt nicht mehr ganz zu.
Vielleicht doch noch mal gucken,
bücken wir mal drauf
Zack, Java Lang System. Und dann gibt es hier
den Outstream, das ist also ein öffentliches Feld.
Und dann kann ich mir den Prince Stream angucken und dann
sehe ich hier eben, da gibt es verschiedene Sachen,
appent, close, Print, Printeln und so weiter.
Also die ganzen Operationen, die ihr so schon teilweise gesehen habt.
Gut. Das sind also jetzt diese Klassenobjekte und dann diese
Felder von den Klassenobjekten oder die Methoden von den Klassenobjekten.
Alles wunderbar. Dann, wie ist das mit
der Initialisierung von so einem Klassenobjekt? Ihr wisst,
wenn ich ein Exemplar in der Klasse habe,
dann kann ich mit einem Konstruktor
die Exemplare initialisieren
Für Klassenobjekte gibt es keine Konstruktoren. Wäre auch
ziemlich schwierig, weil wer soll die denn aufrufen?
So ein Klassenobjekt kommt automatisch in die Welt, in dem Moment,
wo ihr in eurem Java-Programm irgendwie eine Klasse benutzt.
Da wird sie dann geladen. Es gibt so ein Konzept
von Class-Loadern in Java und die laden auf Nachbedarf entsprechend das Klassenobjekt rein.
Und wenn so ein Klassenobjekt geladen wird, dann wird auch ein Klasseninitialisierer ausgeführt.
Den könnt ihr tatsächlich in euren Klassenquelltext reinschreiben.
Ihr könnt also tatsächlich in einer Klasse Konto so etwas schreiben.
Static und dann in geschweiften Klammern das, was gemacht werden soll,
um eure Klassenvariablen zu initialisieren. Wenn ihr sowas also seht,
im Rumpf einer Klassendefinition, dann wisst ihr, dass es ein Initialisierer für das Klassenobjekt.
Nur, dass ihr es mal gesehen habt. Klassenkonstanten,
das ist etwas, was sehr,
sehr weit verbreitet ist in der Java-Welt, nämlich,
dass man Konstanten, die kennt ihr schon,
mit Final Gecancern, das war ein Exemplarkonstanten,
wir konnten jetzt zum Beispiel bei einem Konto sagen,
die Kontonummer ist festgelegt für jedes Konto,
aber man kann die auch mit Static deklarieren und dann sind
sie Static on Final,
dann werden sie zu Klassenkonstanten
Wenn die dann noch öffentlich deklariert sind, dann sind das globale Konstanten.
Und solche globalen Konstanten sind sehr, sehr nützlich,
um so Magic Numbers, die man so im Programm gerne verwendet,
nur an einer Stelle zu definieren. Also zum Beispiel Tage pro Woche,
dann deklariert man das an einer Stelle in einer Klasse,
dann können alle auf diese Konstante zugreifen.
Und wenn dann sich die Tage pro Woche irgendwann mal ändern,
was jetzt da nicht so wahrscheinlich ist, aber Anzahl Spalten meinetwegen,
ich habe irgendwie eine Festlegung von Spalten in einem Editor,
dann möchte ich da nicht sozusagen an allen Stellen jetzt,
wo 80 steht, hinterher feststellt,
ist jetzt hier 80 die Spaltenzahl gemeint oder nicht,
dann müsste ich alle 80 umändern 75, nein,
ich nehme einfach diese symbolische Konstante und alles ist gut.
Damit solltet ihr sehr viel arbeiten mit solchen symbolischen Konstanten.
Wo ihr das wisst, dass ihr sie benutzt,
dann ist es auch sinnvoll, die zu deklarieren.
Klassenmethoden und Variane gibt es auch in der UML-Notation.
Exemplarvariablen ganz normal, Klassenvariablen sind unterstrichen. Also hier,
dass man sieht, ja, das ist unterstrichen.
Das heißt, so viel wie,
es ist eine Klassenvariable oder es ist eine Klassenmethode.
Okay, wir sind fast durch. Das passt wunderbar von der Zeit.
Wir haben gleich noch ein bisschen Zeit für Die Siegerehrung,
nicht alle Objekte sind Exemplare. Was soll das heißen?
Wir haben bisher immer gesagt, Objekt und Exemplar ist das Gleiche.
Der Sprachgebrauch, Java Level 1 bis 3, stimmt das auch.
Wir haben immer gesagt, so ein Exemplar in der Klasse ist ein Objekt.
Jetzt haben wir gerade kennengelernt, Klassenobjekte. Und die sind auch Objekte,
in denen ganz originären Sinne, wie wir sich hier eingeführt haben,
also ein Objekt hat einen Zustand,
so ein Objekt bietet Dienstleistungen an, alles sehr ähnlich.
Damit wir einfach zukünftig ein bisschen genauer sein können in unserer Terminologie,
sagen wir jetzt immer, wenn wir wirklich ein Exemplar meinen,
das ist ein Exemplar,
Und mit Objekt meinen wir sowohl die Exemplare als auch die Klassenobjekte.
Also Objekt ist jetzt quasi unser Oberbegriff. Und Exemplare ist
dann sehr explizit nur für die Exemplare von Klassen.
Denn die Klassenobjekte in Java sind nicht Exemplare von irgendwelchen Metaklassen.
Das ist tatsächlich in anderen Sprachen anders. In Smalltalk zum Beispiel
ist es so, dass eine Klasse immer wieder ein Exemplar ihrer eigenen Metaklasse ist.
Die haben so ein Metaklassenkonzept, sehr raffiniert. Smalltalk ist auch
sehr viel flexibler als Java. In Java ist es so,
ihr könnt eigentlich wenn ihr so eine Klasse mal übersetzt habt,
dann ist die in der Virtual Machine drin.
Da könnt ihr dann nicht mehr viel ändern. In Smalltalk
kann man tatsächlich den Quelltext von den Methoden einfach zur Laufzeit verändern.
Das heißt, ihr könnt dynamisch den eigenen Code verändern.
Kann man sich auch mit ins Knie schießen,
aber ist natürlich sehr mächtig, sehr flexibel.
Das ist also eher was für Experten und Fortgeschrittene.
In Eifel zum Beispiel ist es so,
dass eine Klasse nur ein Konzept ist zur Übersetzungszeit.
Da gibt es zur Laufzeit überhaupt keine Klassenobjekte. Das heißt,
also Java wählt dann so einen Mittelweg zwischen Eifel und Smalltalk.
Es gibt auch noch ganz andere Sprachen,
die haben gar kein eingebautes Klassenkonzept, da ist es einfach so,
jedes Objekt ist einfach definiert als ein Objekt.
Und wenn ich mehr davon haben will, dann muss ich das Objekt klonen.
Das ist ein exemplarbasierte Sprachen. Self, Sessel sind so
die Klassiker, aber auch zum Beispiel JavaScript ist eine objektbasierte Sprache.
Gut, das ist schon die Zusammenfassung, das habe ich
eigentlich, glaube ich, jetzt alles ganz gut erklärt.
Jetzt haben wir noch so ein paar Minuten für die Turtle Graphics,
Creativity Contests 2013 Gewinner. Wie gesagt, wir haben versucht,
das ganze Fair zu haben. Wir haben wirklich tolle Einreichungen gehabt,
wir haben uns schwer damit getan, aber wir haben jetzt die genommen,
die sozusagen am klarsten innerhalb der Regeln geblieben sind.
Also neun Einreichungen. Vielen Dank für die tollen Beiträge.
Einige haben wir
bereits gesehen
Die drei Gewinner. Ich gebe sie jetzt schon mal direkt bekannt.
Die kriegen nämlich jetzt hier Niederägger Marzipan. Das sind Markus
Mayer und Jula Menk, Christina Albers und Dennis Sasinska.
Und die, wenn sie hier sind, noch nicht,
noch nicht klatschen, das machen wir gleich.
Ich zeige die ja erst mal noch. Wenn die hier sind,
dann könnt ihr schon mal so langsam hier runterkommen und sich aufstellen,
damit ich dann hier die Hand schütteln kann vor laufender Kamera.
Dann verkaufen wir gleich den Werbevertrag. Gut,
aber ich muss natürlich auch noch zeigen jetzt hier,
gehen wir mal hier eben ganz kurz rein
TGCC. Die Gewinner. So, gucken wir uns erst mal hier.
Da hatten wir hier das Projekt mit dem Lego-Männchen.
Das fanden wir ganz schön. Ist längst nicht so spektakulär
wie die anderen Projekte, aber irgendwie auch ganz schön.
Jetzt kann ich hier sagen, Lego und dann rufe ich hier auf,
zeichne alles. Ich kann aufrufen, zeichne ein Männchen,
da wird so ein Lego-Männchen gezeichnet oder ich zeichne die Überschrift
und dann ist hierbei Zeichne alles, sieht dann so aus,
dann wird so ein Lego-Männchen gezeichnet.
Das sieht ja relativ harmlos aus, aber das ist im Code relativ schön gemacht.
Also auch diese Kurven sind so relativ raffiniert implementiert. Das ist ganz hübsch,
hat uns gut gefallen und deswegen voll in den Wettbewerbsbedingungen,
deswegen ein Applaus hier für diesen Beitrag.
Dann haben wir die Schneeflocke von Christina. Das sieht so aus.
Wir haben einen Lonteur, da muss ich ihm auch etwas aufrufen.
Und dann gibt es hier, zeichne eine Schneeflocke.
Und ich glaube, die zeichnet dann tatsächlich hier live,
kann man das ganz gut zeigen.
So eine Schneeflocke, das fanden wir ganz hübsch.
Das ist sehr ähnlich zu den Bäumen, die ihren Aufgabenblatt,
boah, weiß ich gar nicht mehr, sieben,
glaube ich, zeichnen solltet.
Das ist hier in der Zeit noch
ganz gut machbar
Was ganz schön ist, wenn man das jetzt mit mehr Verzweigungen zeichnet,
also nicht mit sechs, wie bei einer Schneeflocke,
sondern mit zehn zum Beispiel, dann dauert das sehr viel länger.
Deswegen habe ich das jetzt hier schon mal vorbereitet.
Da habe ich nämlich einfach hier das schon mal, ja,
das ist das Ding und dann sieht das so aus.
Es sieht also irgendwie auch ganz hübsch aus. Ja,
hat uns auch gut gefallen, auch voll in den Wettbewerbsbedingungen drin.
Deswegen hier auch ein Gewinner. Vielen Dank. Und
dann haben wir noch ein auch schönes Projekt. Na,
wo haben wir denn von Dennis Sasinska Das hat uns auch gut gefallen,
weil es so ein schöner Abschluss ist jetzt hier für dieses Jahr.
Ja, hier wird jetzt eine Skyline von Hamburg gezeichnet.
Sehr mühevoll, sehr schön gemacht. Und dann lernen in Hamburg
, ja, toll. Das Motto für dieses Jahr.
Und ich würde jetzt die drei einfach oder die vier nach vorne bitten,
wenn sie denn hier sind,
sind die denn jetzt da, die Leute?
Ja, da ist einer wunderbar. Da sind zwei,
ja, kommt runter, kommt runter.
Es gibt hier jetzt einen Gewinn. Hallo,
du bist
Wo ist Dennis? Genau, wunderbar. Einmal hier,
Niederlage Amazypan, herzlichen Glückwunsch. Sehr schön. Genau,
da kommen gleich zwei, da habe ich eine etwas größere Packung.
Könnt ihr euch teilen. Herzlichen Glückwunsch. Ja. Danke
. Jupp. Und der dritte Gewinner ist nicht da.
Muss ich dann irgendwann demnächst mal, muss ich seinen Gewinnern abholen.
Falls ihr jemanden kennt, soll ich ihn mir
jetzt weit und nein, das mache ich.
Gut, dann sind wir auch schon fast fertig.
Ich wünsche euch fröhliche Weihnachten einen guten Rutsch und ein frohes
neues Jahr.