Juhu. Hallo. Bitte stellt das Sprechen jetzt ein.
Lauter? Soll ich noch lauter sprechen? Soll ich noch lauter stellen?
Ist das nicht laut genug? Doch, laut genug.
Ich höre mich doch sehr deutlich und ihr hört euch.
Ich kann natürlich noch lauter machen. Du machst hier noch
ein bisschen so. Ja, jetzt hört ihr mich auch wirklich.
Toll. Heute ist die letzte Vorlesung vor Weihnachten.
Ja, und dieser Cartoon ist, sagen wir,
nicht mehr ganz zeitgemäß
Ihr wisst ja, dass wir jetzt einen neuen Bundesinnenminister haben.
Aber also im letzten Jahr Weihnachten hätte es noch gepasst.
Ja, okay. Ist auch eher so zum Einstieg jetzt,
ist eher so, weil mir so in den Sinn kam,
dass wir ja jetzt auch immer so klassisch um Weihnachten rum so in unseren Abnahmen.
Da frage ich dann gerne mal nach, na,
wie sieht es denn aus mit den Abnahmen?
Wer hängt denn hinterher? Und dann haben wir immer so
ein paar Kandidaten, die ziemlich weit hinterher hängen.
Und das heißt also, ich frage dann meinen Innenminister,
das ist Christian, wie sieht es denn aus mit den zögerlichen Abnahmen?
Und wer hängt denn hinterher
Und ja, also es wäre gut, wenn ihr nach
wie vor darauf achtet, dass ihr einigermaßen im Plan seid.
Ich vermute, ich spreche jetzt hier genau die Falschen an.
Also diejenigen, die in die Vorlesung kommen,
sind meistens nicht diejenigen, die große Probleme mit der Abnahme haben.
Es sind meistens andere Kandidaten. Okay,
wir haben üblicherweise so Erfahrungswerte von ungefähr 20 Prozent,
die den Schein bei uns nicht machen.
Und das hat ganz verschiedene Gründe. Viele hören einfach auf
zu studieren und ähnliches. Ja,
und wir würden uns wünschen, dass ihr die Chancen nutzt,
die hier geboten werden
Okay. Ein weiterer Punkt ist jetzt,
dass diese Vorlesung klassisch nach Weihnachten stattfindet. Das heißt,
wir haben jetzt Level 1 oder Stufe 1,
2 und 3 von SE1 hinter uns gebracht.
Ihr erinnert euch, Stufe 1 war so alles,
was irgendwie mit Klassen und Objekten zusammenhängt, aber auch mit imperativen Grundlagen.
Level 2 war dann sowas wie, naja, Objekte benutzen sich gegenseitig über Referenzen.
Und Schleifen haben wir dann auch eingeführt, Rekursion. Gut,
und dann haben wir auf Level 3,
das war ein relativ kleiner Level,
so ein bisschen uns angeguckt,
wie man bei einer Klasse unterscheiden kann zwischen der Schnittstelle und
der Implementation
Und dass man dieselbe Schnittstelle durchaus unterschiedlich implementieren kann. Und haben dann gesehen,
dass man Schnittstellen sehr schön in Java mit Interfaces beschreiben kann.
Und dass man auch zum Beispiel gegen ein Interface testen kann,
also eine Blackbox-Testklasse schreiben kann,
die eigentlich nur das Interface benutzt für den Test.
Ja, da haben wir so ein bisschen was über Spezifikationen gehört.
Und ihr habt dann auch das Collections-Framework kennengelernt letzte Woche,
mit dem ihr wahrscheinlich auch schon jetzt eifrig in den Übungen gearbeitet habt.
Und ich hoffe, ihr habt das ein bisschen zu schätzen gelernt,
dass die eigentlich sehr, sehr praktisch sind.
Ihr werdet sie sicherlich noch mehr zu schätzen wissen, Programmieraufgaben löst.
So, jetzt lichten sich die letzten Nebel.
Vor uns liegen jetzt nochmal fünf Wochen. Also heute und
noch weitere vier Vorlesungen. Und wenn wir bisher jetzt
letzte Woche uns angesehen haben, wie man Sammlungen benutzt.
Das ist ja durchaus aller Ehren wert.
Und das ist auch das, was wir primär lernen sollt.
Werden wir uns jetzt ansehen, wie man solche Sammlungen auch
selbst bauen kann. Das wollen wir euch nicht zeigen,
damit ihr zukünftig irgendwelche Sammlungen des Collections Framework selbst baut.
Es ist wunderbar, die zu benutzen, wenn man sie braucht.
Man braucht keine eigenen zu schreiben
Wir machen das primär aus Übungszwecken, weil man,
wenn man versucht, solche Sammlungen zu implementieren,
sehr viel lernt über Datenstrukturen, über effiziente Umsetzungen von Algorithmen.
Und genau das sind die Themen der letzten vier Wochen,
vier, fünf Wochen. Das heißt,
wir werden uns heute ansehen, wie man Arace benutzen kann.
Arace sind relativ schwachbrüstige Listen. Also so, das ist nicht so doll.
Im Vergleich mit den Listen, die ihr schon kennt.
Haben aber auch gewisse Vorteile. Und man braucht Arace sehr,
sehr viel, wenn man effizient Sammlungen implementieren will.
Und wir werden uns dann auch ansehen,
wie man Sammlungen implementieren kann mithilfe von verketteten Listen und ähnlichem.
Und wir werden uns auch noch Hash-Verfahren ansehen, damit ihr endlich versteht,
warum Equals und Hash-Code in dieser Beziehung zueinander stehen.
Die vielen von euch haben wir aus den Übungen mitgekriegt.
Noch nicht so richtig hundertprozentig klar sind. Gut,
aber heute geht es eigentlich nur um zwei Themen.
Ein fokussiertes Thema sind Arace. Und ein zweites Thema heute
ist Klasse. Klasse als Objekt, Klassenmethoden, Static in Java
. Das gucken wir uns auch noch an.
Bevor ich jetzt innerlich einsteige, würde ich aber gerne noch
ein paar Worte zur Modulprüfung sagen, weil da ja schon nachgefragt wurde.
Wir machen eine schriftliche Prüfung, also eine Klausur in SE1.
Es gibt zwei Termine, wir bieten also tatsächlich zwei Termine
an, die sind gleichwertig. Es ist nicht so,
dass wir irgendwie androhen, wer nicht zum ersten Termin kommt,
muss zum zweiten kommen und das ist viel schwieriger oder sowas,
machen wir nicht.
Es ist alles Blödsinn. Wir machen zwei gleichwertige Klausuren.
Es ist nur empfehlenswert zuerst zu gehen,
weil wenn man dann durchfällt,
dann kann man eben halt noch
relativ schnell wiederholen
Deswegen, klassisch ist das so eingeführt worden mit den
zwei Modulprüfungen in der Pause zwischen den Semestern,
damit man relativ leicht wieder auf den Stand kommen kann.
Gut, diese beiden Termine sind am 6. Februar, am 19. März,
dauere jeweils zwei Stunden außer einem Stift, dürft ihr nichts verwenden,
also kein Skript mitbringen oder irgendwelche elektronischen Geräte oder sonst irgendwas.
Wir machen das als Multiple-Choice-Klausur. Das heißt,
wir geben stellen Aussagen an den Raum und ihr müsst dann
sagen von diesen Aussagen, ob sie richtig oder falsch sind.
Ihr müsst also nur binär entscheiden. Das ist was,
was Informatiker ja besonders gut können.
Ja oder nein? Entweder ist genau eine Antwort richtig,
also meistens so einer aus vier, muss aber nicht eins aus vier sein.
Und manchmal sind es auch engrichtige Antworten, also was weiß ich,
zwei oder drei aus sechs oder sowas.
Ja, und wir haben auch eine Probeklausur, ins Komsi gestellt. Das heißt,
wer da noch nicht das entdeckt hat,
es gibt jetzt da eine Probeklausur,
die ist tatsächlich auch etwas netter oder etwas realistischer als die Probeklausur,
die wir die letzten Jahre mal rausgegeben haben,
weil wir jetzt auch tatsächlich mal den gesamten Stoff so ein bisschen abgedeckt haben.
Also so, vorher war es halt nur so eine
halbe Klausur
Ja, könnt ihr euch gerne angucken. Wenn da noch
Fragen dazu sind, könnt ihr gerne im Kommen sie dazu posten.
Und es wird sicherlich sich jemanden finden von uns,
der das beantworten kann. Aber im Großen und Ganzen gibt
es bei uns keine negativen Überraschungen, was Klausuren angeht.
Ich würde jetzt nicht sagen, dass unsere Klausuren einfach sind.
Ich denke, man muss schon die Übung mitgemacht haben,
um sie bestehen zu können. Auch wenn man das gemacht hat,
dann hat man auch eine sehr gute Chance zu bestehen.
Also das ist tatsächlich so, wer die Übung vernünftig mitgemacht hat.
Hat keine Schwierigkeit zu gestehen. Ich sage jetzt nicht,
dass er deswegen eine Eins kriegt oder sie,
aber bestehen sollte drin sein
Gut. Ja, also jetzt tatsächlich zum eigentlichen Thema.
Arrays. Und wie gesagt, Sammlung sind ein wichtiges Thema.
Man braucht die fast überall, benutzt überwiegend das Glections-Framework,
aber manchmal ist auch ein Array eine gute Datenstruktur der Wahl.
Und wir werden uns das jetzt mal ein bisschen ansehen.
Und wir melden das relativ technisch machen. Ich werde am Anfang
ein bisschen was Allgemeines sagen zu Rays, was unabhängig von Java gilt.
Und dann, wenn wir uns sehr genau angucken,
wie man in Java mit Arrays umgeht.
Das ist eine ziemlich technische Vorlesung heute.
Als wenn die anderen Vorlesungen nicht auch technisch gewesen wären.
Jetzt mal ein Anwendungsbeispiel zum Einstieg. Nehmen wir an,
wir haben irgendwie eine hochsetaugliche Boje und das ist erstmal nur den Typ,
den wir da haben. Wir haben dann vielleicht tausende von,
die dann irgendwo strategisch günstig auf den Weltmeeren platziert sind und
diese Dinger messen den ganzen Tag munter Temperaturen und speichern die irgendwo ab im 10 Minuten Abstand,
im Stundenabstand, was auch immer.
Da werden also sozusagen Messwerte im Speicher abgelegt.
Jetzt sind die Dinger, sagen wir mal, sehr teuer,
weil die müssen halt extrem temperaturbeständig sein, wasserbeständig und so weiter.
Das heißt, der Speicher ist vielleicht auch ein teurer Speicher,
also speicher ein kostbares Gut und deswegen sollte man den Speicher möglichst gut ausnutzen.
Und da bietet sich tatsächlich so ein Array ganz gut an.
Naja, weil es eben halt sehr nah am Speicher dran klebt.
Also Array sind tatsächlich sehr speichernah. Also ein Speichernahes Konzept
. Das ist ein klassisches imperatives Sprachkonzept,
also in den meisten imperativen Sprachen gibt es Arrays.
Und also auch in Pascal oder natürlich auch in C und C plus plus.
Eine Sammlung von Elementen, gut, das kennt ihr.
Wir haben ja schon sowas wie Sammlungen diskutiert und
man greift auf ein Element über einen Index zu
Und sie sind eigentlich Listen mit einer festen Größe.
Ihr erinnert euch die Listen, die ihr aus dem Collections-Framework benutzen könnt.
Sind unbegrenzt, keine feste Größe, wunderbar.
Race haben eine feste Größe. So,
und was ein Array eigentlich nur ist,
und das ist wirklich, was man sich klar machen muss,
eine Ray ist so eine Millimeter dicke Abstraktion über dem Speicher.
Wenn ihr so einen, den von Neumann-Rechner habt mit dem großen Speicher,
ihr wisst es, dann ist das mehr oder weniger
so eine Ebene so gerade mal so ein bisschen drüber.
Also oberhalb der Grasnarbe quasi. Nämlich, dass ein Array
so etwas ist wie ein Segment im Speicher. Ich sage einfach,
dieser Teil des Speichers zusammenhängt, ein Segment,
ist immer etwas Zusammenhängendes im Speicher, das sei mein Array,
hält also hier, man sieht mehrere Zellen.
Und diese Zellen kann ich indizieren und üblicherweise beginnt bei Null,
wie ihr das ja auch von anderen Sammlungen schon kennt.
Oder auch von Zeichenketten kennt. Und das ist mehr oder weniger das,
was man wissen muss, über ein Array,
das ist tatsächlich eine sehr speichernde Struktur ist.
Jetzt kann man, das habe ich ja schon gesagt,
naja, benutzt eigentlich am liebsten die Collections aus dem Crackson Framework
Aber es gibt so Fälle, da eignen sich Arrays ganz gut.
Und ein Beispiel sind so Bilddaten. Also so,
wer von euch jetzt noch nicht so sich intensiv mit
so digitalen Bildern beschäftigt hat, ist es tatsächlich so,
diese ganzen Bilder, die hier so auf den Speicher,
auf den Computern rumliegen.
Früher war das noch weniger selbstverständlich. Heute habt ihr alle
eine Digitalkamera und wenn nicht im Handy, dann vielleicht irgendwo noch woanders.
Und diese Digitalbilder sind eigentlich nichts weiter als eine ganz lange Kette von einzelnen Bildpunkten.
Beginnt oben links meistens und dann irgendwie zahlenweise so und dann
hat man irgendwie so, so sind die logisch aufgebaut.
Das heißt, das sind alles Bildpunkte und
jeder Bildpunkt hält eine Information
Wie hell er ist, welche Farbe er hat und so weiter.
Das sind jetzt hier mal so ein paar Beispiele mit Schwarz-Weiß-Bildern.
Und weil man häufig auf solche Bilddaten zugreifen will,
um sie zu manipulieren,
also Photoshop, habt ihr vielleicht auch schon mal gehört,
dann möchte man mit jedem Bildpunkt irgendetwas tun.
Ich möchte zum Beispiel alles heller oder dunkler machen.
Ich habe hier mal Bluejay dabei mit einem Projekt,
das ihr auch diese Wochen in Übungen bearbeiten werdet.
Das ist, sagen wir, eines der beliebten Projekte.
Nur am Rande bemerkt, ich benutze jetzt Bluejay 304.
Es gibt momentan Aktuelles BlueJ 306,
aber seit BlueJ 305 gibt es Probleme mit Arrays.
Das würde mich sehr stören bei meinen Präsentationen gleich,
wenn ich Arrays hier live zeigen will.
Deswegen habe ich 304 genommen. Also wenn ihr in den
Übungen auch Probleme kriegt mit Arrays, in der Direkteingabe,
dann wisst ihr, es liegt an der BlueJ-Version.
Nur so als kleiner Hinweis. Nicht nur mit der Direktangabe,
aber mit zweidimensionalen Arrays beim Debuggen auch.
Also das sind eher so Randprobleme. Also beim Debuggen Direkteingabe,
also nicht unbedingt so gravierend. Diese Aufgaben solltet ihr bearbeiten
können. Da haben wir keine Sorgen.
Also in diesem Projekt geht es dann darum, dass ihr hier Schwarz-Weiß-Bilder habt.
Also SW steht für Schwarz-Weiß-Bild. Und man kann jetzt hier irgendwie als Konstrukte,
kann ich hier einen Pfad angeben, wie war das hier,
kiss.give, glaube ich, das müsste funktionieren.
Dann habe ich hier ein solches Image. Das ist jetzt
sozusagen ein Bild, das ist nur eine Referenz auf dieses Bild.
Und das ist mehr oder weniger nichts weiter als ein Zweidimensionales Array von Bildpunkten.
Und ich kann jetzt hier verschiedene Dinge tun mit diesem Bild,
also ich kann es dunkler machen,
ich kann es heller machen, uns horizontal spiegeln oder ähnliches.
Das ist alles noch nicht implementiert, soweit ich weiß,
in diesem System hier. Das werdet ihr dann bauen in den Überu.
Was wir hier schon vorgegeben haben, ist zum Beispiel das Dunkler.
Ich kann zum Beispiel jetzt sagen, hier 40 dunkler, was heißt 40?
Also diese Bildpunkte haben einen Helligkeitswert von 0 bis 255.
255 ist weiß, 0 ist schwarz. Und wenn ich jetzt hier sage,
mach das mal dunkler und 40 Bildpunkte, dann wisst ihr,
naja, das ist ungefähr ein Achtel, Achtel dunkler.
Dann wird jeder einzelne Bildpunkt dunkler gemacht. Ich kann das
hier auch nochmal, man kann das hier auch vergleichen mit
dem Bild da unten.
Das ist nämlich ungefähr
das Gleiche
Sieht man, dass das da oben jetzt tatsächlich
dunkler geworden ist und das hier ist noch das Original.
Da kann man eben hier so die nochmal nach vorne
holen und den und den. Und ich kann das jetzt
auch nochmal machen, kann also hier nochmal sagen, mach
das mal dunkler. 40 und dann wird das noch dunkler.
Also tatsächlich nichts weiter als auf jedem Bildpunkt irgendwie sagen, dunkler machen.
Naja, intern ist das tatsächlich relativ einfach gebaut.
Hier ist ein zweidimensionales Array. Ihr seht immer so
ein Beispiel, ein zweidimensional Array von Short.
Short sind halt so, ihr wisst so 16 Bit.
Ins, mehr oder weniger
Ja, und dann hat man hier eine Bereitung,
eine Höhe für so ein Bild.
Und dann werden hier diese Bilddaten eingelesen und dann sieht man
hier so zum Beispiel das Dunkler, wie es gebaut ist.
Das ist tatsächlich, hier wird das Delta angegeben,
um das etwas dunkler gemacht werden soll.
Dann wird hier erstmal geprüft, ob es denn irgendwie kleiner Null ist.
Das macht ja keinen Sinn. Dann wird es einfach umgedreht, sehr nett. So,
und dann ist hier einfach eine Vorschleife durch alle Zeilen des Bildes,
dann innerhalb jeder Zeil einer Vorschleife durch die Breite,
also durch alle Spalten.
Und dann wird hier irgendwas mit jedem einzelnen Bildpunkt gemacht.
Also zum Beispiel wird hier irgendwie dieses Delta abgezogen
Von dem Wert, der an diesem Bildpunkt gespeichert ist.
Also auch digitale Bilder sind überhaupt keine Hexenkunst. Letztendlich total einfach. Gut,
die Algorithmen, die man da drauf bauen kann,
da kann es schon mal richtig kompliziert werden.
Also es gibt da ziemlich viele Möglichkeiten. Ihr seht ja hier auch,
wir haben hier uns ein bisschen was ausgedacht,
so weich zeichnen und spiegeln und Spot und so.
Das ist teilweise einfach, teilweise nicht so einfach.
Das werdet ihr in den Übungen sehen. Und ich denke,
das macht auch Spaß, da einfach mal so ein bisschen zu sehen,
wie das, was man tut, tatsächlich sofort Wirkung zeigt an so ein Bild.
So, und da ist es einfach so,
Bilddaten sind deswegen ein gutes Beispiel, weil man eben halt da schnell darauf zugraten will.
Könnt ihr euch überlegen,
wenn ich so ein Bild habe mit tausendmal tausend Bildpunkten,
was jetzt nicht so groß ist, eure Fotos heutzutage sind meistens größer.
Also das eine Million Bildpunkte. Das heißt, ich muss
eine Million mal irgendwie eine Operation auf einem Bildpunkt ausführen.
Das kann schon mal dauern. Wenn ihr mit so einem
Filter in Photoshop mal gearbeitet habt, dann wird euch das
auch schon aufgefallen sein, dass die teilweise länger dauern.
Ich höre es irgendwie laut sprechend, wenn ihr liebt,
wenn ihr nicht zu laut redet,
weil sonst irgendwie andere Leute schlecht zuhören können.
Gut, also ein Beispiel, Bilddaten, schnell zugreifbar, deswegen Array.
Also Arrays haben ja so Effizienzvorteile, gehen wir nochmal drauf ein.
Ein anderes Beispiel sind so Spielfelder fester Größe.
Also sowas wie TikTok Toro habt ihr ja nun schon gesehen.
Schach, Schach hat 8 mal 8 Felder, ein Schachbrett.
Das ist selten anders. Es ist relativ langweilig,
Schach auf einem 3 mal 3 Spielfeld zu spielen.
Bei Go ist das wieder anders. Go hat 19 mal
19 Schnittpunkte auf dem Feld. Da kann man auch mal
mit 9 oder mit 11 oder mit 13 Schnittpunkten spielen,
klar. Aber auch sowas wie viel Gewinn zum Beispiel,
ich weiß nicht, wer viel Gewinn kennt,
können wir uns gleich nochmal angucken
Kommt noch ein bisschen später,
wo man dann irgendwie vier irgendwie in eine Reihe bringen muss.
Und bisher haben wir ja Arace nicht gekannt.
Und ihr erinnert euch, dass wir zum Beispiel TikTak-Toe gebaut haben,
ohne Arace und einige von euch, die Arace schon kannten.
Die fanden das ziemlich hässlich, vielleicht auch zu Recht.
Aber es war ja auch zumindest sehr hilfreich, mal zu sehen,
dass man so ein Spielfeld ja durchaus unterschiedlich implementieren kann.
Also hier das Spielfeld, das Interface, die Schnittstelle,
da möchte man eigentlich nur von TikTak-Toe aus irgendwie sagen können,
ich möchte auch diesen neuen Zellen irgendwie einen Spieler setzen oder
wegnehmen und ich möchte abfragen können,
ob der Spieler gesetzt ist
Und kann vielleicht noch fragen, ob es voll ist, das Spielfeld.
Na, das kann man eben halt implementieren. In dieser Klasse Spielfeldgeflecht,
die wir, glaube ich, vorgegeben haben, ist es so,
dass da hier in der Klasse drei Exemplarvariablen sind.
Hier zahle 0 Zeile 1, Zeile 2. Und wenn man da jetzt irgendwie auf eine bestimmte,
auf eine Position zugreifen wollte, gibt Besitzer,
hier zum Beispiel Zeile und Spalte,
dann war das hier relativ zu Fuß gemacht mit so einem Switch über die Zeile,
damit hier irgendwie Case 01,
2 gemacht,
dann wird hier hart kodiert auf diese eine Exemplarvariable jeweils zugegriffen und dann in der Gib mir mal den Besitzer von der Spalte.
Das ist nicht so schön. Das geht deutlich besser,
mit einem zweidimensionalen Array. Das werden wir uns gleich mal angucken.
Da ist das dann deutlich kompakter und eigentlich auch besser verständlich.
Das ist schon relativ komplex hier. Man sieht hier,
ist nochmal so eine weitere Klasse notwendig, Spielfeldzeile.
Das ist so eine klassische objektorientierte Lösung. Keine besonders gute,
aber eine mögliche. Gut, das erstmal so auch als Motivation.
Ich habe ja gesagt, Arrays haben eine feste Größe.
Bei solchen Anwendungsfällen Ist das total wurscht, dass die eine feste Größe haben,
weil es hat ja auch die Fachlichkeit, die wir modellieren,
ein Spielfeld, ist auch fest groß.
Von daher, wunderbar, da bieten sich Array sofort an für sowas.
Okay. Ja, das ist jetzt mal so eine Übersichtsfolie,
die werde ich nicht im Einzelnen jetzt zerklären. Das heißt,
das ist erstmal nur die Übersicht und ich gehe jetzt richtig schön langsam durch,
was man mit Array so machen kann.
Und wir werden sozusagen hier Schritt für Schritt uns dem nähern.
Sehr technisch. Ich habe jetzt die Anwendungsbeispiele schon ein bisschen gebracht.
Wir werden jetzt erstmal uns sehr technisch ansehen,
was kann man mit Arrays machen und was kann man
mit denen nicht machen und worauf muss man achten,
was ihr euch erstmal in der Übersicht klar machen sollt.
Das ist eigentlich eher eine Folie, die am Ende nochmal
so alles zusammenfassen könnte. So könnte man sie auch sehen.
Also ein Array ist eine geordnete Reihe und gleichartige Elemente.
Die Elementtypen können Basistypen oder Referenztypen sein. Anders als bei
den Sammlungen von Collection Framework. In this is,
da kann man nur Referenztypen reinschmeißen,
um da etwas anderes reinzuschmeißen, musste man diese Rapperklassen benutzen.
Länger eines Arrays wird erst beim Erzeugen festgelegt. Jeder Zugriff wird automatisch geprüft. Okay,
das sind so Eigenschaften, die sind wichtig,
insbesondere auch für Leute, die jetzt aus der C-Welt kommen,
weil da wird das zum Beispiel nicht immer garantiert,
dass man über einen Index,
dass da auch geprüft wird.
Gut,
fangen wir mal langsam an
Das erste ist, wenn ihr einen Array benutzen wollt,
müsst ihr einen Array deklarieren. Wie immer, wenn ihr
irgendetwas machen wollt in Java, müsst ihr euch eine Variable deklarieren.
Gut, ein Array ist im Java immer ein Objekt.
Okay, das heißt, wenn ich eine Array Variable deklarieren
will, ist das Klingeling eine Referenzvariable.
Alles, was nicht von einem primitiven Typ ist, ist eine Referenzvariable.
Also falls sich es irgendwann noch nicht erwähnt haben sollte,
dass Referenzen wichtig sind. Spätestens jetzt würde ich es gern
nochmal betonen. Also auch wenn man Arrays verstehen will,
Das kann man nicht, wenn man nicht Referenzen verstanden hat.
Also das insbesondere, wenn dann zweidimensional oder mehrdimensional wird,
da muss man einfach kapieren, was eine Referenz ist.
Und so, hier haben wir also wieder ein Beispiel.
Ein Array ist also immer eine Referenzvariable. Das heißt,
übrigens habe ich ja schon vergessen, eine Ray ist immer ein Objekt.
Das heißt tatsächlich, alles, was man mit einem Objekt
machen kann, kann ich auch mit einem Array machen.
Das werden wir vielleicht nochmal ein bisschen sehen. Gut,
der Typ dieser Varianten ist als Array von Element-Typ definiert.
Also ich kann sowas schreiben wie Int-Array. Das ist
sozusagen hier die Syntax, wie man ein Array deklariert,
eine Array-Variable. Das ist der Typ,
also Int-Array
Und meine Variable heißt hier Interray. Gut. Und Länge
und Größe wird Interklaration nicht angeben. Ihr habt erstmal nur
eine Variable und ihr wisst, das ist eine Referenzvariable,
also die ist erstmal null, das ist mit Stritten.
So, dann sieht das aus, Syntax-Array-Deklaration.
Es gibt die Möglichkeit, das irgendwie mit innen zu machen.
Man kann aber auch ein Array von Personen deklarieren oder von
Konto oder von Spielfeldzeile oder ähnliches. Also jede beliebige,
jeder beliebige Typ kann ein Elementtyp in einem Array sein.
Da gibt es keine Einschränkung. In Java. So,
nächster Schritt, wir haben jetzt
eine Array-Variable
Ich könnte ja mal so nebenbei, vielleicht so hier, sowas mal machen.
Ich sage hier, Int, Array, I-A-R-R. So,
zack. Habe ich mal so eine Variabliche deklariert.
Ja. Das ist toll. Da ist sie jetzt.
Ich kann jetzt irgendwie I-A-R mal irgendwie mir angucken. Da
sagt er, das ist null. Ja, hat er recht.
Das ist einfach null bisher. Ist ja nichts drin.
So, jetzt muss ich also so ein Aray erstmal erzeugen.
Das ist wie mit den Objekten. Ich kann in eine Referenzvariable nur etwas reinstecken,
was eine Referenz ist und eine Referenz muss immer auf irgendetwas
verweisen auf ein Objekt und da Arays Objekte sind,
muss ich auch ein Aray-Objekt erstmal erzeugen.
Das ist diese Syntax hier. Sowas wie New in 8.
Was hier erzeugt wird, ist ein Aray für acht Elemente.
Also ich kann also auch sowas schreiben hier,
mein Interray ist gleich und dann wird das hier gleich bei der Deklaration initialisiert.
New in 8. Und tatsächlich können wir uns das so vorstellen,
das hier ist das Aray-Objekt, so ein Speicher,
wo irgendwie acht Elemente reinpassen.
Ja, das kann man direkt so machen. Also kann ich
auch hier mal schreiben, mir jetzt IAA ist gleich.
New in 8. Zack. So, jetzt habe ich eine Objektreferenz.
Ich habe also jetzt tatsächlich meiner Variablen das zugewiesen.
Ich habe hier ein New aufgerufen. Es wird ein Array-Objekt
erzeugt. Und das kann ich jetzt mir auch möglicherweise angucken,
aber ich habe jetzt hier eine Referenz, die kann ich hier gleich mal rüberziehen.
Gut, das ist jetzt erstmal wichtig, also Variable,
das ist eine Referenzvariable, muss ich mir erstmal ein Exemplar erzeugen.
So sieht diese Syntax aus für die Erzeugung
Ich muss es mit New machen, ich gebe den Typ
an und dann gebe ich hier eine Expression an.
Ganz wichtig, da muss kein Literal stehen.
Ich habe das gerade mit zum Beispiel der Acht gemacht,
die Acht ist ja ein Literal.
Das heißt, der Compiler sieht zur Übersetzungszeit, aha,
das Array soll acht Elemente groß sein.
Das muss da nicht so deutlich stehen. Da kann auch
eine Variable stehen. Sowas wie New Person und dann ist X
irgendein ganz zahliger Wert. Und der kann zur Laufzeit,
kann dieses X sich ja ändern. Das heißt also,
es ist zur Übersetzungszeit bei einem Array nicht festgelegt, wie groß es ist.
Und es wird erst zur Laufzeit festgelegt. In diesem Fall hier
habe ich es jetzt tatsächlich mit so einer mit einem Literal gemacht,
also mit einer Konstanten. Ja. Und wie gesagt,
auch da wieder kann man mit beliebigen Elementtypen machen.
Dann ist es so, wenn ich ein Array erzeuge,
dann ist dieser Speicherbereich belegt mit sinnvollen Werten.
Das ist garantiert. Das heißt,
wenn ich zum Beispiel ein Array von Int-Werten anlege,
was ich hier gerade gemacht habe, ich habe hier meinen Array von Int-Werten,
ich kann das ja mal hier rüberziehen, dann seht ihr es mal.
So, hier habe ich meinen Ich nenne das mal so
ähnlich wie, ja, ist ja egal. So,
das ist jetzt hier mein Array und das kann ich mir
auch mit dem Objektinspektor anzeigen lassen und so sieht das aus.
Es hat hier irgendwie die Länge und dann hat man hier
diese ganzen Zellen und ihr seht, die sind alle mit dem Wert null belegt.
Ja. Weil tatsächlich für jeden Element-Typ gibt es einen Default-Wert,
also eine Voreinstellung, einen Anfangswert und der wird eben halt genau gewählt.
Das ist genau wie bei den Exemplarvariablen,
wenn ich ein Exemplarvariable von einem Typ deklariere,
gibt es immer einen Default-Wert für die Objekttypen,
also für die Referenztypen ist es immer null und für Alle anderen primitiven Typen halt der entsprechende, der dazugehört.
Also bei End-Null, bei Bulian Falls und so weiter.
Man kann auch sowas schreiben hier. End-Array ist gleich mit
diesen geschweiften Klammern. Das ist tatsächlich ganz schick.
Dann kann man manchmal so relativ kurz angeben, wie man
seine Dinger befüllen will. Hier haben wir ja gerade,
in meinem Beispiel habe ich das hier hier live gemacht.
Ich kann aber auch jetzt hier meiner variablen IAR, kann ich auch,
wie haben wir das hier gemacht, auf der Folie.
Das geht natürlich jetzt nicht. Ich kann aber eine End Array,
Variable, I-A-R-R-2 deklarieren und bei der Initialisierung,
kann ich jetzt schreiben, das sei irgendwie 1,2,3,4.
Und dann habe ich hier ein,
muss ich vielleicht noch eine Mikola dahinter machen,
weil das ist ja eine, naja, okay,
es muss ein Simikolan sein.
Ich habe irgendwo hier noch so einen Tab, nee,
Simikolan? So, jetzt haben wir unser I-A-R-2.
Und das ist auch eine Objektreferenz auf ein Array.
Das ist ein neues Array hier
Und da stehen jetzt die Werte von 1 bis 4 drin,
weil ich das hier direkt bei der Initialisierung mit angegeben habe.
Diese geschweiften Klammern sind halt nur zulässig an der Deklaration.
Also wenn ich das Ding direkt initialisiere. Okay,
also ihr könnt nicht sowas als aktuellen Parameter übergeben,
an irgendeiner Stelle, wo ein Array erwartet wird.
Ja, gut, dann Rays werden beginnt bei null indiziert.
Auch das ist keine Überraschung, das kennt ihr von den
Strings schauen. Ja, die Informatikwelt ist halt grausam.
Man muss immer bei null anfangen. Und gültig initiiert sind
entsprechend null bis Länge
Klar. Also eine Ray, der Größe 8,
hat zum Beispiel gütig in die CS0 bis 7. Also hier
mein Array mit Temperaturen drin.
Hier ist meine Referenzvariable. Hier ist die Referenz auf
mein Array und da stehen irgendwelche Werte drin.
Und es sind halt acht. Deswegen gültige Indizes 0 bis
7. Sehr schön. Dann ist es auch wichtig,
dass man auf solche Array-Zellen nicht nur Lesen zugreifen kann.
Ich kann also zum Beispiel jetzt hier auch in meiner Direkteingabe
sagen, was ist denn in I-A-R-R-R-R-R-R-2 drin?
Dann sagt er mir, da ist die drei drin.
Und dann gucke ich da mal eben hoch
Siehe da, er hat Recht an Index. 2 ist
die 3 drin. Kann ich also lesen, darauf zugreifen.
Ich kann aber auch schreiben, darauf zugreifen. Ich kann
es einfach sagen. IAR2 soll gleich sein 17. Zack.
Dann habe ich jetzt hier in meinem Aray an der Stelle 2 eine 17 reingeschrieben.
Ich kann also das sowohl auf der rechten Seite stehen haben,
dann lese ich es aus oder auf der linken Seite,
dann schreibe ich es rein. Auch das ist etwas,
was ihr kennt. Also hier lesender Zugriff in Ausdrücken,
schreibender Zugriff, weil Zuweisung üblicherweise auf der linken Seite.
Ja, gut. Dann ist es auch so,
dass ich schon gesagt habe, in einem Array können verschiedene Elementtypen drin sein.
Alle Elementtypen, die Java bietet, tatsächlich auch primitive Typen.
Also unser Temperaturen-Array kann tatsächlich hier so Werte direkt enthalten.
Bei den Objekten, wenn man ein Objekttyp als Elementtyp hat,
dann ist natürlich in dem Array nicht ein Array von Objekten gegeben,
sondern in dem sind wieder nur Referenzen auf die Objekte.
Das kennt ihr. Ich meine, ihr wisst immer,
dass man Objekte nicht irgendwo speichert. Das heißt,
so eine Zelle eines Arrays ist eigentlich so etwas wie eine Variable,
die ihr schon kennt. Also eigentlich ist eine Array so
was wie eine Sammlung mit Zusammengehörige Sammlung von Variablen,
die man speziell benennen kann, mit diesen eckigen Klammern.
Ja, also das ist auch ganz wichtig,
dass man gucken muss, was ist denn da so drin?
Ist es ein Referenztyp, dann sind da halt tatsächlich Referenzen drin,
wenn es ein primitiver Typ ist,
dann sind in dem Array-Objekt selbst tatsächlich primitive Werte.
So, jetzt gibt es so ein paar klassische Fehler,
die man machen kann mit Arrays,
die sollten wir mal eben einmal ganz kurz durchgehen.
Also angenommen, wir haben eine Railing Größe 8. Habe ich
ja gerade erzeugt. Dann kann ich tatsächlich jetzt sowas versuchen,
wie greift auch mal auf Position 8 zu.
Ich weiß ja, es ist acht groß,
also muss acht Jahre gehen. Klar, klassischer Fehler,
ich darf ja nur von 0 bis 7,
aber ich habe das irgendwie nicht bedacht.
Also sage ich jetzt hier mal acht.
Also wenn ich hier mal in meinen Blue Jay gehe,
wenn ich mich recht erinnere, war das hier dieses etwas größere Array.
Ich mache das hier mal ein bisschen kleiner,
wenn man es besser sehen kann. So, hier ist
das Array. Jetzt sage ich hier in 1,
das ist, das sind zwei Referenzen auf dasselbe.
IAR1 oder in eins ist das Gleiche hier in eins von acht.
So, da greife ich mal drauf zu. Und dann
sagt er, ups. Also doch IAR 1 von acht.
So. Toll. IAR. Ist eine Objektreferenz. Ah,
das Ding heißt IAR. Gut, also ich habe eine Referenz.
So, jetzt greife ich da endlich auf die Acht zu.
Verdammt, zack, das wollte ich eigentlich erreichen.
Es gibt eine Exception. Ich habe auf einen falschen Index zugegriffen
Und der klassische Fehler ist halt, dass man um einen daneben greift.
Man kann aber auch um beliebig anderen Wert daneben greifen.
Ein Array, der größte Acht, halt als gültige Indizes,
0 bis 7. Ich kann auch eine 35 angeben,
eine minus 17, alles falsch.
Führt immer zu einem Laufzeitfehler. Das geht erst zur Laufzeit,
weil man ja erst zur Laufzeit weiß, wie groß ist das Array?
Können ja unterschiedlich groß sein. Gut. Das ist der erste
typische Fehler. Zweiter typischer Fehler, das Array-Objekt ist nicht erzeugt.
Ich habe also irgendwie eine Exemplarvariable, sowas wie Numbers.
Ist ein In-Array, ist natürlich aber eigentlich erstmal noch
eine Referenzvariable
Und im Konstrukte schreiben wir irgendwie Num von Numbers von Null,
soll 42 sein. Das heißt, wir greifen über diese Referenzvariabel
auf ein Array zu, was aber gar nicht da ist.
Das heißt also, hier ist tatsächlich das Ding nicht erzeugt worden.
Ich muss also erst mal das New-In schreiben, bevor ich
da was reinschreiben kann. Muss halt Arrays erst erzeugen.
Auch das ist einfach technisch detail, aber es muss halt verstanden sein.
Nicht die Möglichkeit ist, bei einem Referenztyp als Elementtyp,
also wenn ich einen Array habe von Konten zum Beispiel,
ich habe eine Klasse Konto,
dann erzeuge ich mir hier zwar meine Array-Objekt.
Also hier habe ich tatsächlich mein Array-Objekt erzeugt, mit New Konto 4.
Jetzt sage ich irgendwie, Konto 0.1 zahlen. Ja,
ich versuche jetzt direkt auf einem dieser Konten,
wahrscheinlich auf diesem hier Konto 0, rein Zahlen aufzurufen.
Aber dummerweise haben wir da noch gar keine Objekte drin.
Bei einem Array von Referenztypen muss ich natürlich auch erstmal
die Objekte, die da rein sollen, erzeugen.
Und das darf man nicht vergessen. Es kann aber sehr leicht passieren
, dass man das vergisst. Das sind alles Fehler,
die man eben halt macht,
wenn man nicht das richtige mentale Modell hat von Arrays und Ich denke,
wenn man sich das hier so ein bisschen verinnerlicht,
was hier auf den Folien ist, dann ist das eigentlich nicht mehr so schwer.
Gut, wenn man sowas hat wie eine Sammlung, wisst ihr,
dann will man meistens auch was machen mit allen Elementen in der Sammlung.
Und Race haben so eine ganz lustige Eigenschaft. Die haben
eine öffentliche Exemplarkonstante. Ich kann also tatsächlich jetzt hier von meinem Array,
VRR, kann ich sagen, gib mir mal die Länge.
Und dann sagt er, das ist acht.
Und was ihr gesehen habt, ist, ich habe jetzt
keine runden Klammern dahinter geschrieben.
Das heißt, das ist kein Methodenaufruf oder kein Operationsaufruf
Sondern es ist tatsächlich ein Zugriff auf ein Feld.
Eine Exemplarvariable. Eigentlich ist es eine Exemplarkonstante. Ja,
das heißt, ein Array hat eine Exemplarkonstante, die sozusagen
bei der Erzeugung festgelegt wurde. Wir haben ja festgestellt,
ein Array bei der Erzeugung wird festgelegt, wie groß es ist.
Und dann behält es diese Größe auch. Na,
dann haben sie halt in so einer Konstante kodiert,
wie groß es ist. Das ist eben halt auch effizienter.
Und man spart sich einen Methodenaufruf, der das irgendwie kapselt.
Hier kann man jetzt sozusagen direkt darauf zugreifen. Das ist auch
nicht schlimm, weil man kann das Ding nicht verändern.
Das ist eine Konstante. Ja, also längst ist tatsächlich
hier gut zugreifbar. Und was man dann häufig macht,
ist, wenn ich etwas mit einem Array machen will.
Ihr könnt so ein Array natürlich auch als Parameter übergeben.
Hier ist ein formaler Parameter Interray vom Typ, Array of Integer.
So, und das wird hier übergeben.
Und mit einer Vorschleife kann ich jetzt hier drüber iterieren,
indem ich einfach alle gültigen Indizes benutze, die ich benutzen kann.
Also fangen bei null an. Und solange ich kleiner ist als Array.längs,
wir wissen, der höchste Index,
mit dem ich zugreifen kann, ist genau längst minus eins,
also solange ich kleiner ist als die Länge,
passt das wunderbar, mache ich irgendetwas mit dem Interray,
also in diesem Fall,
hier wird es einfach ausgegeben,
mit System Outprinting
Das nennt man ein Programmiermuster, das nennen wir ein Programmiermuster,
man nennt es auch im Englischen, nennt es auch ein Edium.
Eine bestimmte Art und Weise, wie man klassisch auf Elemente in einem Array zugreift.
Wenn man etwas mit allen Elementen machen will. Also wenn ihr sowas seht,
dann könnt ihr das auch,
wenn ihr ein bisschen Übung habt mit Java-Programmierung,
relativ schnell lesen und sagen, ah ja, okay,
man geht jetzt mal eben hier null kleiner, ja,
ja, genau.
Also mit allen Elementen was machen. Alternativ habt ihr
ja schon die erweiterte Vorschleife kennengelernt letzte Woche.
Kann man die auch verwenden? Ich kann also auch tatsächlich
etwas knapper sagen. Ich habe hier die gleiche,
den gleichen Methodenkopf, also eine Methode Print Array,
die ein Array von Int als Parameter bekommt.
Und hier steht dann einfach nur noch vor Int K,
für jedes Int K in dem Int Array, System Out Printin Car.
Das heißt, in jedem Rumpf,
in diesem Rumpf habe ich in jedem Schleichen Durchlauf,
hat das K einen anderen Wert, nämlich genau alle Werte,
die in dem Array abgelegt sind.
Da muss man allerdings aufpassen. Ja, wenn man das
so macht mit der erweiterten Vorschleife, hat man erstens keinen Index.
Ihr habt auf der anderen Da war ein I,
ein Zähler, den man mitgeführt hat. Das heißt,
ihr könnt im Schleifen Rumpf, jetzt zum Beispiel das Array, selbst nicht verändern.
Ihr könnt also jetzt nicht irgendwie auf das Array an der Position zugreifen,
wo ihr gerade seid und sagt, ich möchte das jetzt ändern.
Wenn ihr so etwas tun wollt über ein Array mit
einer Schleife rüberlaufen und das Array dabei selbst verändern,
solltet ihr nicht die erweiterte Vorschleife nehmen.
Gut, also auch hier für jeden INK im Interratur-Irgendwas.
Es gibt keinen Schleifenindex und ihr könnt am Array selbst nichts ändern.
Geht einfach nicht. Manchmal ist das praktisch, manchmal ist
das Eher nicht geeignet. Okay. Ich habe mal hier
ein Beispiel. Das ist im Skript ein bisschen anders.
Da habe ich das mit dem maximalen Wert gemacht.
Ich fand es irgendwie noch mal ganz lustig,
das mal mit einem im Minimum zu machen.
Nehmen wir mal dieses Beispiel hier, ich habe also eine Methode,
finde Minimum, bekommt ein Array von Int.
Ich weiß nicht, wie viele Elemente drin sind,
weil der Typ sagt ja nichts darüber, wie viele drin sind.
Und ich möchte jetzt den minimalen Wert finden. So,
das ist hier die Schleife, die hier steht.
Ich setze zuerst mal meine Minimum, mein angenommenes Minimum auf
den größtmöglichen Wert.
Intiger Max Value
Das ist etwas, was wir uns gleich auch noch angucken werden.
Ich kann also tatsächlich den größten möglichen Intwerte nehmen und dann
hoffe ich natürlich, dass mein Minimum kleiner ist. So,
dann laufe ich hier wieder durch meinen Array durch und mache hier
einen Vergleich mit dem Minimum und wenn die aktuelle Zelle,
die ich betrachte, einen kleineren Wert enthält,
dann setze ich das Minimum neu.
Und am Ende schmeiße ich das Minimum raus. Wir haben hier
eine Benutzung davon. Wenn ich das jetzt mal hier so aufrufe,
also das ist der Klient,
das andere ist der Dienstleister da oben und jetzt habe ich hier einen Klienten,
jetzt mache ich hier sowas wie My Array ist hier eigentlich New in 10.
Dann fülle ich hier was rein, My Ray 0,
My Array 1, Mary Air 2, sind 20, 40, 30.
Und dann sage ich, hier Finde Minimum, also genau,
ich rufe meinen Finde Minimum auf und dann möchte ich das ausgeben lassen.
So, jetzt ist die große Quizfrage an dieser Stelle für diejenigen,
die jetzt eingeschlafen sind, weil das alles so langweilig war.
Was kommt denn da jetzt raus? Null. Null.
Andere Vorschläge? Hat jemand noch einen anderen Vorschlag?
20. Auch ein Vorschlag
Gut, wir machen eine kleine Abstimmung. Wer ist für
20? Zwei, drei. Wer ist für null?
Wow. Ihr habt alle gut aufgepasst. Natürlich ist es
so, dass dieses Array hier zehn Elemente enthält.
Und bei der Erzeugung werden alle Elemente alle Zellen des Arrays
auf den Werten null initialisiert.
Wir schreiben jetzt in drei Zellen Wertereien,
aber diese Methode hier geht tatsächlich durch alle zehn Zellen.
Das Array ist durch. Und das stehen natürlich dann
auch noch sieben Nullen drin. Und deswegen ist null
das Minimum
Muss man also sehr aufpassen. Das ist ein klassisches Missverständnis,
das in einem Array, wenn man etwas hineinfügt,
dass dann auch nur so viele Elemente drin sind.
Aber eine Array hat immer so viele Zellen, wie es groß ist.
Und jedes Array hat da einen anderen Wert dafür. Gut,
hier nochmal die Alternative mit der neuen Vorschleife kann man es auch machen.
Auch möglich. So, jetzt ein weiterer Punkt,
der spannend ist oder was heißt. Nicht spannend, aber wichtig.
Zuweisung einer Array-Variablen kopiert nur eine Referenz. Das heißt,
wenn ihr sowas habt wie hier,
ein In-Array wird deklariert und auch gleich initialisiert und dann weist ihr,
dass einander zu, Habt ihr, ihr wisst es,
es sind Referenzvariablen, deswegen verweisen dann beide Referenzen auf dasselbe Array-Objekt.
Möglicherweise nicht das, was man erwartet, wenn man allen Array zuweist.
Denn eigentlich weist ihr an dieser Stelle nicht, ein Array zu,
sondern ihr weist nur die Array-Variable zu. Gut,
wenn man tatsächlich aber dieses Ding hier kopieren will,
dann gibt es zwei Möglichkeiten, entweder mache ich das elementweise,
schmeiße ich die rüber in ein neues Array-Objekt,
lege mir ein neues Array-Objekt an mit der gleichen Größe von dem Alten und schaufel die ganzen Elemente rüber oder ich verwende Klon.
Klon ist also tatsächlich für Arrays implementiert,
wir gucken uns das mal an
Oh, das ist ja interessant. Da habe ich eine doppelte Folie drin.
So, also, kopierend von der Ray hier.
Ich kann tatsächlich also meinen Array erzeugen. Dann kann ich
hier sagen, new int. Und dann sage ich,
mit der gleichen Größe wie das andere Array, also interray.lanks.
Und dann mache ich eine Vorschleife und sage hier,
jedes Element aus dem einen Array schaufle ich in das Array rüber.
Und dann habe ich hinterher tatsächlich die Situation, dass dann
das so aussieht. Mit Clone kann ich es auch machen.
Sieht ein bisschen einfacher aus. Also ich kann tatsächlich hier
meinen Array erzeugen. Und dann sage ich hier,
rufe ich auf dem ersten Arraiders Clone auf und das liefert mir
wirklich eine Kopie des Arrays mit den enthaltenen Elementen drin.
Ganz hübsch, ganz praktisch in manchen Situationen. Okay.
Ja, dann gibt es natürlich auch noch die zweidimensionalen Arrays.
Und ich würde mal sagen, wir fragen erst mal,
ob es irgendwie noch Fragen gibt zu den eindimensionalen Arrays.
Ja, im Klo nicht. Prinzipiell nur Object zurück,
dass wir da noch Versuchssicherung machen müssen
Er fragt, ob das Klon nicht nur ein Objekt zurückliefert.
Etwas vom Typ Object. Jein, das stimmt,
aber das Klon ist tatsächlich in Array so definiert,
dass es etwas von dem konkreten Typ wiedergibt, von seinem eigenen Array-Typ.
Das heißt, ich kann tatsächlich, das hier ohne
einen Typ zur Sicherung zu weisen. Sehr spannende Frage,
aber tatsächlich ist das zum Glück nicht notwendig in Java.
Man kann tatsächlich, wenn man das Klon redefiniert,
also Array hat das Klon, was von Object geerbt ist, redefiniert.
Genau, wie man das Equals-Serie definieren kann,
haben wir letzte Woche gesehen
Und beim Klonen kann ich auch sagen, der Ergebnistyp soll ein anderer sein.
In dem Fall ist es dann der von dem Array selbst.
Das funktioniert ganz gut. Noch eine Frage zu allen dimensionalen Arrays.
Da ist noch eine Frage. Sehr schön. Er fragt,
ob der Indextyp implizit Integer ist oder long.
Das ist eine gute Frage. Ich denke mal,
es ist Int
Tatsächlich nicht hundertprozentig sicher. Ich würde vermuten,
dass es eben ist, weil das heißt,
dass man vier Milliarden Elemente indizieren kann.
Und so als Java definiert wurde, war das noch unvorstellbar
viel Zeug. So Anfang der 90er. Ich meine,
auch heute ist das so relativ viel Zeug. Ja,
aber so vier Gigabyte Hauptspeicher hat man ja heute schon.
Und dann kann man da schon mal vier Milliarden Zellen im Speicher adressieren.
Aber ich meine, es ist Int als Index-Typ.
Ja, da ist noch eine Frage. Was wäre denn,
welches Int-Array 2 auch kleiner wäre, beziehungsweise größer.
Die würden sich ja auch nicht anfallen,
weil den Int-Array einvermuten
Das habe ich jetzt nicht ganz verstanden. Das ist Dilerate
2, ne? Ja. Das ist weiter weg.
Ja. Ein kleiner oder größer auf jeden Fall als das
erste Away. Die Juliane war die Stadt rein.
Okay, jetzt habe ich die Frage verstanden.
Ja, ich habe es verstanden. Also die Frage ist,
was ist denn, wenn in Array jetzt kleiner ist?
Das ist tatsächlich, jetzt kann hier nicht passieren.
Also in diesem Fall ist ja der Code hier ganz eindeutig.
Das zweite Array wird ja initialisiert mit einem Array der gleichen Größe wie das andere.
Wenn ich jetzt zwei, ich kann natürlich vom gleichen Typ
zwei Arrays haben, die unterschiedlich groß sind.
Ich kann einen Interray haben von acht Elementen und eins von
sechs Elementen
Ich jetzt versuche, in einer Schleife alle acht Elemente in
das sechs Element hier rüber zu schaufeln, gibt es einen Indexfehler.
Das heißt also, Index out of bounds,
weil bei dem sechs Elementing darf ich halt nicht auf Index sechs zugreifen.
Und auf sieben. Noch eine Frage. Jo, lieber
gerne nur eine Referenz zurück. Clone liefert nur eine Referenz,
ja. Naja, Clone liefert auch ein neues Objekt.
Ja, ich würde erzeugt, aber der liefert die Referenz auf das neue Team.
Ja, also Clone liefert eine Referenz auf ein neues Objekt
zurück, genau eine Referenz.
Und aber das Clone ist eben halt für Arrays so implementiert,
dass es genau so groß ist wie das geklote Objekt
Also bei dem Klon kann das auch nicht schiefgehen,
dass es irgendwie kleiner ist. Okay, noch Fragen.
Erstmal keine. Dann würde ich sagen, da ist noch eine.
Kamerastreets. Nochmal. Das kann man jetzt auch machen.
Assoziative Arrays. Oha. Das ist jetzt eine große Frage.
Was meinst du damit? Ja, so zum Beispiel,
ja, so ein Swingsing-Streets zunächst.
Ein String als Index, okay. Nee,
das geht in Java nicht. Also man kann tatsächlich
nur mit
ganz zahligen Werten indizieren
So, ich glaube, dann sind erst mal so alle Fragen gestellt.
Dann machen wir jetzt fünf Minuten Pause und gucken uns dann zweidimensionale Arrays an.
Kommen Sie rein, kommen Sie rein, es geht weiter.
So, jetzt kommen wir zu einem etwas komplizierteren Fall,
nämlich zweidimensionale Arrays. Die sind deshalb etwas komplizierter,
weil sie, ja, man muss etwas verstehen,
nämlich die Sache mit den Referenzen.
Ich zeige erst mal noch mal wieder Tic-Tac-Toe eine andere Lösung,
nämlich die Lösung mit einem Array
Und da sieht man hier, ja,
das ist die eine Lösung, Spielfeld, Spielfeld,
Geflecht, Spielfeldzeile, das ist das, was ihr kennt.
Und das hier ist die Lösung mit einem Array.
Und diese Lösung ist deutlich kleiner. Ja,
man sieht hier, da ist eine Deklaration eines zweidimensionalen Arrays,
das Spielfeld hier intern, Referenz, Variable,
dann wird hier im Konstruktor dieses Array initialisiert.
Und dann gibt es hier sowas wie... Es gibt Besitzer
und dann macht man einfach nur noch einen Zugriff hier.
Spielfeld, Zeile und Spalte. Genau, oder hier besetzte
Position, Spielfeld, Bei der Spalte wird irgendwas zugewiesen.
Also hier steht es auf der linken Seite.
Also ganz überschaubar, ich habe noch etwas anderes.
Vier gewinnt. Wer von euch kennt, vier gewinnt?
Aha, kennen ziemlich viele, sehr schön.
Mir wurde nachgesagt, ich würde schummeln.
Bei Spielen in der Vorlesung. Das hat mich so empört,
dass ich jetzt euch eine Chance gebe, gegen mich anzutreten,
im Vier gewinnt.
Mir,
das hattet ihr schon mal
Zitatoren. Ja, ich sag ja,
da habt ihr ja gesagt, ich würde schummeln.
Und jetzt spiele ich ehrlich. Ehrlich. Gibt es denn
da zu lachen? Also, es ist, viel gewinnt
es so, man kann irgendwie immer eine Spalte auswählen.
Und ich spiele jetzt mal, ich klicke jetzt hier mal
rein und dann bin ich gelb.
So, jetzt dürft ihr mir zurufen, wo ich rot hinsetzen soll.
Oben drauf. Links daneben, obendrauf, obendrauf.
Ich nehme euch ernst. So, ich setze mir mal
hier einen hin. Rechts? Hier? Ja.
Gut. Okay, ich setze hier einen hin
Ich bin ein lausiger, vier Gewinnspieler. Das ist die Stumme.
Frechheit. So, wo soll ich den Roten hinsetzen?
Was? Dann ist es genau unter uns.
Genau da, hier. Hier. Unten, hier.
Okay, interessant. Ich setze mal hier einen hin.
Ihr da drauf? Da drauf? Ja, ja.
Okay, ich setze hier einen hin
Zweiter von rechts. Also hier, dann setze ich da einen hin.
Ich habe schon... Ich habe dich wohl missverstanden.
Na gut. Ihr seht, viel gewinnt,
kann man auch mit dem Computer spielen.
Das ist eine Variante hier, die zwei Spieler zulässt.
In den Übungen habt ihr eine mit so einer kleinen künstlichen Intelligenz.
Dann könnt ihr gegen den Computer spielen. Der ist auch
gar nicht so schlecht. Wenn ich jetzt hier nochmal klicke,
dann geht es wieder von vorne los.
Also das ist viel gewinnt. Und für diejenigen,
die es nicht kennen, Das sieht in Wirklichkeit so aus.
Das ist tatsächlich ein echtes Vier-Gewinnspiel. Das ist so ein
Plastikgerüst und dann wird man diese Chips da oben rein,
dann fallen die so runter. Also eigentlich sind das so
Spalten und dann kann man da irgendwie die Dinger reinsetzen.
Genau. Das ist also die Assoziation, die man haben sollte.
Und man sieht hier wieder, das passt einfach sehr gut.
Das kann man sehr gut mit zweidimensionalen Arrays machen.
Beruhigt euch wieder. Es war jetzt auch nicht so gemein von mir.
Okay. Ganz wichtig ist, wenn man sich jetzt vorstellen will,
wie zweidimensionale Arrays and Java gebaut sind,
dann muss man sich das klar machen,
dass ja ein Ray-Objekt immer irgendwie hängender Speicher ist.
Und dass so ein Array, ja, ein Elementtyp hat.
Und tatsächlich habe ich jetzt hier,
wenn ich jetzt sage, ich habe ein zweidimensionales Array,
eine Variable A, als zweidimensionales Array von Endwerten,
dann ist es eine Referenz auf ein Array.
Und in diesem Array sind Arrays drin. Also ist hier
der Elementtyp eindimensionales Array und das hier ist ein eindimensionales Array.
Es sind also mehrere eindimensionale Arrays hier und hier haben wir,
da ist der Typ zweidimensionales Array,
hier ist der Elementtyp eindimensionales Array und hier ist der Elementtyp dann
In, in diesen einzelnen Zellen drin. Das ist eigentlich nicht
so schwer, aber man muss halt so ein bisschen,
wie gesagt, diese Referenzen ganz gut verstanden haben.
Man kann jetzt zweidimensionale Arrays einmal so erzeugen, wie das hier angedeutet ist.
Also hier sowas wie Int-Array, das ist dann hier zweidimensional.
Man gibt also einfach zweimal diese Array-Klammern an. Dann kann ich hier sagen,
New-Ind 5, und da sieht man schon,
in der ersten Dimension erzeuge ich jetzt hier dieses Ding.
Das ist mein erstes Objekt, das ich erstmal erzeuge.
Dann laufe ich durch diese fünf Elemente durch, 4NE5,
mache ich hier dann ein New-Ind
Das heißt, hier erzeuge ich dann nacheinander diese Elemente.
Das kann ich auch direkt schreiben.
Ich kann auch einfach schreiben, new in 4 und 5.
Ich kann das auch noch mal live zeigen.
Also ich kann hier hinschreiben, new int, 3,
3. Dann habe ich hier tatsächlich jetzt eine Objektreferenz.
Und das ist wie übrig. Ich kann die hier erst mal rüberziehen,
mein interray. Und jetzt ist das Schöne mit dem Objektinspektor,
ich kann tatsächlich jetzt hier mir das anzeigen lassen.
Dann sehe ich hier, es ist ein Array-Objekt mit
drei Referenzen auf
Ja, a race. Also das sind jetzt drei verschiedene Arrays.
Und die sind keine Überraschung, alle mit null initialisiert.
Ja, das ist also mehr oder weniger das,
was hier jetzt zu sehen ist.
Es ist sozusagen, ich habe hier eine Referenz auf dieses Irre-Objekt
und da sind drei Referenzen drin auf.
Man hat ja so wieder so eine Art Objektdiagramm gebastelt.
Und das ist hier mehr oder weniger so das Gleiche,
was hier auch zu sehen ist.
Wenn ich jetzt auf ein zweidimensionales Array zugreifen will,
dann mache ich das einfach über so einen doppelten Array-Index-Zugriff
hier.
Also zum Beispiel hier Roe Callum
Dann wird auch auf das richtige Element zugegriffen.
Ich kann also zum Beispiel jetzt hier in meinem Beispiel,
hier kann ich jetzt sagen, ich muss hier erstmal,
glaube ich, diese Referenz, nee, in eins,
Punkt, nee, nicht Punkt, in eins,
eins, also an der Position 1-1,
weiß ich jetzt mal eine 17 zu.
Ich hoffe mal, dass das funktioniert. Zack,
das müsste funktioniert haben, das heißt,
jetzt habe ich hier
meinen Objektinspektor
Da ist mein Moment, da ist mein Objekt.
Und in einem dieser Arrays müsst ihr jetzt eine 17 stehen.
Tatsächlich, ich habe jetzt an Zeile 1
und dann Spalte 1 habe ich wirklich eine 17 reingetragen.
Das hat also funktioniert. Und so greift man da halt darauf zu.
Nicht weiter spannend. Spannender wird es jetzt, wenn man das kopieren will.
Also wenn man jetzt anfängt, sich zu überlegen,
wie kann ich denn so ein mehrdimensionales Array auch kopieren?
Da muss man halt wieder sehr aufpassen. Also man kann
das erstmal von Hand machen, mit dem ich tatsächlich durch
zweidimensionalen Zweitdimensionen durchlaufe und immer entsprechend diese Dinger da erzeuge.
Oder ich kann tatsächlich auch Klon benutzen, aber Clone ist nicht rekursiv implementiert.
Das heißt, wenn ich jetzt hier meine wunderbaren Elemente habe,
ja, da ist noch eins so,
ich will ja eigentlich den hier noch sehen, so,
den möchte ich noch haben.
Jetzt kann ich tatsächlich schreiben, in 1.clone. So,
ich glaube, es muss sich ja irgendwie umlassen,
damit das funktioniert, muss ich jetzt hier sagen,
in noch ein, zweidimensionales Irrway, nämlich Int-Array 2 so.
So, das kann ich so zuweisen. Also es wird
sozusagen hier direkt initialisiert. Ich deklariere eine variable Int-Array 2,
haben Typ 2 Dimensionals Int-Array und sage, es soll ein Klon sein.
Das geht so. Jetzt kann ich hier mir dieses Int-Array
2 noch mal anzeigen lassen und kann das hier rüberziehen.
Und was ich habe, ist tatsächlich ein anderes Array.
Aber dieses Array ist jetzt nur eine Kopie von diesem,
also nur die oberste Ebene ist jetzt kopiert worden.
Wenn ich jetzt hier Auf diese Referenzklicke,
dann ist das, welche Überraschung, das Ding.
Weil natürlich einfach die Inhalte mitkopiert wurden. Oder wenn ich hier draufklicke,
das heißt, die beiden Arrays zeigen auf dieselben eindimensionaten Arrays.
Diese beiden zweidimensionalen Arrays hier. Ja,
das ist also tatsächlich auch nochmal zu beachten an der Stelle.
Wenn man eine vollständige Kopie machen will,
dann muss man tatsächlich von Hand sozusagen sich darum kümmern,
diese Dinger zu erzeugen.
Das ist relativ schnell so ein bisschen kompliziert. Und deswegen
muss man das gut verstanden haben, wie diese Referenzen da gebaut sind.
So, gibt es jetzt noch Fragen zu Race,
mehr dimensionalen Arrays, klassische Frage.
Geht das auch dreidimensional? Klassische Antwort, ja. Klar,
ich kann da beliebig viele Dimensionen bauen, ist ja logisch.
Das ist ja irgendwie nur eine Frage von Verschachtelung.
Ja, sonst noch Fragen zu Arrays, dann würde ich
jetzt noch mal so ein bisschen was sagen zu Arrays.
Also warum sind die überhaupt da? Warum gibt es die überhaupt? Naja,
es ist tatsächlich so, dass wenn man an einer Programmiersprache sehr dicht am Speicher arbeiten will,
ist es gut sowas wie Arrays zu haben,
weil zum Beispiel der Zugriff auf ein Element in I'm Array ist etwas,
was in einer auf jeder vernünftigen Rechnerarchitektur direkt abgebildet werden kann.
Es gibt also tatsächlich in der Rechnerarchitektur, auf dem Prozessor,
auf dem das Ganze läuft, immer einen Befehl,
mit dem man irgendwie indiziert zugreifen kann, man sagen kann,
hier ist irgendwie eine Adresse im Speicher und ab da,
ab der tausendsten Stelle,
greift da mal drauf zu und es geht wirklich schnell.
Das ist wirklich ein ganz schneller Zugriff. Also der Ray-Index-Zugriff hier
, der kann einfach sehr gut und effizient abgebildet werden.
Und auch ganze Rays zu kopieren, also so ein Speicherbereich,
einfach Blockweise woanders hin kopieren, nicht irgendwie von Hand,
sondern dieses Clone ist idealerweise auch ein bisschen schlauer gebaut,
dass es tatsächlich auch auf einem Maschinenbefehl abbildet und dadurch
einigermaßen schnell ist
Naja, und dann ist es außerordentlich so, dass man
die Arrays in Java auch zulassen, dass man elementare Typen einführt.
Man kann also wirklich Array von Int schreiben und muss nicht
diesen komischen Umweg gehen über List von Intiture oder so, mit diesen Rapper-Objekten.
Ja, Nachteile. Grüße ist festgelegt zur Übersetzungszeit,
muss kein Nachteil sein, wenn die Fachlichkeit sowieso feste Größen vorsieht.
Und was auch relativ schnell, sagen wir,
lästig wird mit einem Array, ist,
dass ich so nicht die mächtigen Operationen habe.
Erinnert euch daran, bei einer Liste konnte ich irgendwie sagen,
so ich möchte an Position etwas einschieben,
ein Objekt und dann sind alle Elemente
verschoben worden
Das ist bei einem Aray nicht gut möglich. Ich kann
bei einem Aray, habe ich immer so eine Zellenvorstellung.
Und ich kann auch in eine Zelle was reinschreiben.
Aber wenn ich wirklich was dazwischen packen will,
dann muss ich selbst von Hand in dem Aray alles um einen Index verschieben,
damit ich dann da in die Lücke was reinpacken kann.
Also das ist, also so Sachen wie Anfügen oder auch Einfügen,
entfernen mit dem Aufrücken und auch Testaufenthalten sein.
Das sind alles so Sachen, die sind nicht sehr komfortabel.
Da braucht man ein bisschen mehr dafür.
Und da sind natürlich dann die Collection-Framework-Sachen deutlich komfortabler.
Okay. Ja, das war es zu Arays.
Alles andere macht ihr dann in den Übungen
Beziehungsweise jetzt habe ich hier noch einen Vergleich. Gut,
das habe ich aber eigentlich schon gesagt, zusammenhängende Speicherstellen.
Insgesamt ist es tatsächlich so, das ist vielleicht nochmal
so ein Satz, den ihr euch merken solltet.
Die Arace sind eigentlich auf einem niedrigeren Abstraktionsniveau.
Also diese Sammlungen des Collections Framework, die benutzen auch Arrays,
um sich selbst zu implementieren oder um Implementen zu werden.
Aber Race sind halt immer so ein bisschen dichter am Speicher.
Gut, das ist das alles, was man zu Arace
sagen kann. Könnt ihr euch in Ruhe nochmal durchlesen.
Ich komme jetzt nochmal zu einem anderen Thema,
das erstmal nichts damit zu tun zu haben scheint,
aber dann doch gewisse Beziehungen hat, werden wir gleich aufzeigen.
Was ihr bisher verstanden habt, ist eine Klasse,
ist sowas wie eine Vorlage für ganz viele Exemplare.
Ich kann also von einer Klasse beliebig viele Exemplare erzeugen.
Eigentlich habt ihr schon die Unterscheidung zumindest mal mitbekommen.
Es gibt eine Klassendefinition. Das ist sowas wie der Text,
der die Klasse beschreibt. Und dann gibt es auch die Klasse,
weil von so einer Klasse kann ich ja dann zur Laufzeit
auch mit New mir neue Exemplare bauen lassen.
Klassisch ist tatsächlich so die Sichtweise in der Objektentdetenprogrammierung des Klassen
so Einheiten sind im statischen Programmtext, während Objekte,
Einheiten des laufenden Programms sind.
Das seht ihr auch in den UML-Diagrammen. Es gibt einmal
UML-Diagramme, das sind Klassendiagramme. Da ist es so,
dass die statische Struktur eines Systems beschreiben.
Während Objektdiagramme immer so Schnappschüsse sind von laufenden Systemen.
Also da kann man schon auch da an der UML sehen,
dass das verschiedene Dinge sind. Aber es gibt tatsächlich die Möglichkeit,
dass Klassen selbst auch zur Laufzeit irgendwie da sind.
Wie das aussieht, ist in verschiedenen Sprachen unterschiedlich gebaut.
Und in Java ist es eben halt so ein Mittelweg zwischen Klassenwerden zu
fett eigenständigen Objekten und ich kann einfach zur Laufzeit gar nicht auf Klassen zugreifen.
Also Java hat da so einen Mittelweg und den gucken wir
uns jetzt mal an. Also erster Punkt ist,
ich kann tatsächlich eine Klasse auch zur Laufzeit als ein Objekt ansehen.
Und so ein Klassenobjekt hat dann auch einen Zustand.
Ich kann tatsächlich bei einem Klassenobjekt, bei einer Klasse definieren,
dass sie eine Klassenvariable haben sollen.
Das ist das klassische Beispiel, was hier auf der Folie ist.
Ich möchte die Exemplare zählen, die von meiner Klasse erzeugt werden.
Das ist jetzt nicht so ein wahnsinnig spannendes Beispiel,
aber eben halt, sagen wir, sehr anschaut, das ist so eine Metainformation.
Ich habe also meine Klasse und dann habe ich ganz viele Exemplare
und möchte ich jetzt zählen, wie viele sind denn erzeugt worden?
Dann mache ich einfach im Konstruktor hier, erhöhe ich diesen Zähler, Exemplar-Sähler.
Und dieser Exemplar-Sähler ist eben halt eine Static-Variable. Das heißt,
alles, was zu einer, zum Klassenobjekt gehört,
wird mit dem Schlüsselwort Asthetic deklariert. Das heißt,
wenn diese Klasse zur Laufzeit irgendwie auch ein Objekt ist,
mit einem Zustand, habt ihr genau eine Variable,
diesen Exemplar-Sähler und jedes Exemplar von der Kontoklasse hat natürlich ihren
eigenen Saldo und so weiter, was ihr alles kennt,
aber nur Ein Objekt existiert ein Konto-Klassenobjekt.
Und das hält dann diesen einen Zähler und dann kann eben
halt dieser Zähler auch ausgelesen werden.
Also wir haben hier zum Beispiel eine Operation, Anzahl erzeugt
der Exemplare und die liefert das dann für einen Klienten.
Wie sieht das aus, wenn so ein Klient das rufen will?
Das ist ganz einfach. Ihr kennt das von dieser Punktnotation.
Ich muss ein Objekt angeben, Punkt und deinen Operationsnamen.
Das ist jetzt hier genauso bei den Klassenoperationen.
Ich gebe den Klassennamen an. Punkt. Und deine Klassenoperationen
. Also zum Beispiel hier kann irgendwie ein Kontenverwalter,
macht irgendwelche Prüfungen und sagt jetzt hier,
Anzahl Konten ist gleich Konto
To.anzahl erzeugte Exemplare. Also man kann sich tatsächlich so
eine Klasse auch als ein Objekt vorstellen.
Das ist tatsächlich in Java auch so modelliert.
Es kann einen Zustand haben, der Zustand kann geändert werden,
der Zustand kann sondiert werden, sehr ähnlich.
Das ist jetzt, sagen wir, ein Beispiel gewesen,
wo eine Klasse einen Zustand hat. Häufig ist es aber so,
dass diese Klassenoperation genau dann eingesetzt werden, wenn man irgendwas hat,
was möglichst nicht von irgendeinem Zustand abhängig sein soll.
Es gibt zum Beispiel Paket Jabba Util gibt es eine Klasse Arrays.
Die bietet so ein paar statische Operationen an,
mit denen man irgendwie so Dienstleistungen auf Arrays anbieten kann.
Also zum Beispiel, ich glaube auch Array, ein bisschen komfortabler kopieren und ähnliches.
Also hier zum Beispiel Array-Copy. Und ein anderes Beispiel,
was ich vielleicht mal zeigen könnte, ist,
wenn wir mal hier irgendwie, haben wir mal was Vernünftiges,
da so, ich kann zum Beispiel sagen, Java,
also es gibt auch Moment,
Moment,
Hier. Java Lang Mars ist eine klasse Mars,
ist eine Klasse. Und die bietet auch Dienstleistungen an,
also statische Operationen. Und zum Beispiel ist da möglich,
aufzurufen, ich muss jetzt gar nicht Java Lang angeben,
weil Mars, es gehört ja zu Java Lang,
also zur Sprache, ich kann also schreiben Mars,
Punkt, Pau, Power, 2, 10.
Das ist 2 to the Power of 10, also 2 hoch 10.
Ich kann also da tatsächlich jetzt exponieren mit. Ja,
und dann kommt tatsächlich was raus. Zum Beispiel 1024 in diesem Fall.
Das ist tatsächlich so dieses Mars, Objekt hat keinen Zustand.
Das sind ja Funktionen, das ist ja eine Funktion.
Das heißt, der Wert des Ergebnisses ist nur von den Parametern abhängig.
Nicht von irgendeinem Zustand, von dem Mars-Objekt. Also in
dem Sinne nicht wirklich objektorientiert. Also gerade wenn man so Funktionen hat,
dann werden die häufig so als statische Methoden beziehungsweise Operationen modelliert.
Ja. Dann gibt es ja nicht noch ein schönes Beispiel.
Warte mal eben, was ist denn mit Intager?
Max Value, das ist eine Konstante. Ja, kann
man auch abfragen. Es gibt aber auch in Integer,
sowas wie Integer, Pass Int.
Und da kann ich jetzt eine Zeichenkette angeben. Und aus
der Zeichenkette kann ich dann mir eine Zahl bauen lassen.
Also Integer Pass Int, 1, 2, 3.
Da gebe ich also eine Zeichenkette an. Eins, zwei,
ihr kennt ja, wenn man irgendwie Eingaben hat in grafischen Oberflächen
, kann man irgendwelche Zeichen eingeben.
Und da jetzt so eine Zeichenkette umzuwandeln in eine ganze Zahl.
Das kann man dann, kann man Integer Pass Int benutzen.
So, und dann sieht man, hier kommt 1,
2, 3 raus.
Und natürlich, wenn ich da jetzt was Falsches eingebe,
also irgendwie was, keine Zahl ist.
Und er soll daraus jetzt ein Idiger passen,
dann gibt es schwupps eine Exception. Also das ist auch nicht
weiter überraschend. Im nächsten Semester lernen wir dann auch,
wie man solche Exceptions auch auffangen kann und damit umgehen kann und so weiter.
Gut, aber das sind so Beispiele für solche Dienstleistungen.
Und ja, jetzt kommen wir zu einer meiner Lieblings, zu einem meiner Lieblingsthemen.
Das ist nämlich die wunderbar spezielle Klassenoperation Main. Jedes Java-Lehrbuch,
das nicht das wunderbare Lehrbuch von Barnes Kölling ist,
fängt irgendwie mit diesem Beispiel an.
Wir schreiben unser erstes Stava-Programm, Public-Static Word Main, Hello World.
Das ist so der Klassiker. Wenn ihr jetzt euch das mal anguckt,
was da drin steckt, in diesem unschuldigen kleinen,
dieser Signatur dieser Methode hier, in diesem Kopf einer Prozedur,
einer Operation, dann ist das ganz schön viel Zeug.
Jetzt inzwischen habt ihr alles, was ihr wissen müsst,
um das verstehen zu können.
Also ihr wisst, was Public heißt.
Public heißt, es gehört zur Schnittstelle von irgendeiner Klasse.
Static heißt, das ist eine Klassenmethode oder eine Klassenoperation.
Void heißt, liefert nichts zurück. Main ist
der Name und String Ray Arcs ist einfach ein Array
von Zeichenketten
Das ist sehr schön. Und wenn genau so eine Methode in einer Klasse definiert ist,
dann kann man diese Methode von außerhalb eines Java-Systems aufrufen.
Das heißt, vom Betriebssystem aus kann man sozusagen den Einstieg finden in Java-Code.
Ihr könnt also Java-Code von Betriebssystemen aus aufrufen. Das ist,
wie gesagt, klassisch die Art und Weise,
wie Java-Programme gestartet werden in klassischen Entwicklungsumgebungen. Ich habe tatsächlich,
als ich aus Australien zurückkam, 2001,
dann 2000 war ich noch in Ulm für ein paar Monate
Habe ich auch Blu-Jay mitgebracht und hat irgendwie einen Professor das
auch dann einsetzen wollen da in der Lehre und kam irgendwann ganz aufgeregt zu mir und sagte,
wo ist denn der Startknopf in Blu-Jay?
Man kann ja gar nicht die Main-Methode starten. Ich fürchte,
der gute Mann hatte nicht verstanden,
dass Blu-Jay einfach viel mächtiger ist, nämlich jedes Objekt aufrufen kann,
dass man damit eben halt Objektorientierung sehr schön üben kann.
Und diese Main-Methode, die kann man im Blu-Jay natürlich
auch aufrufen, das gucken wir uns jetzt mal an.
Ich zeige euch erst mal, wie man tatsächlich so
eine Main-Methode mal schreiben kann.
Ich mache dazu mal Folgendes. Ich gehe mal hier
auf dieses nette Windows-Tool CMD
So, jetzt flackert der Bildschirm einen Rücksturz in die Vergangenheit.
Das hier ist eine sogenannte Konsole, eine Kommandokonsole.
Damit kann man jetzt direkt Kommandos eintippen. Ich kann das
jetzt zum Beispiel hier irgendwie, ich mache mal folgendes,
ich will ja jetzt ganz bestimmt was tun, was ganz Bestimmtes tun.
Ich möchte genau in diesen Ordner gehen hier. Ja,
und jetzt mache ich hier tatsächlich CD. Jetzt muss ich hier irgendwie,
das geht nämlich nicht so einfach mit Copy und Paste.
Ich muss jetzt irgendwie hier sagen, einfügen, so,
zack, jetzt stehe ich in dem Verzeichnis.
Jetzt kann ich hier sagen Deal und siehe da,
er macht hier
ein Listing
Ja, das sieht genauso aus wie das hier.
Das ist genau das Gleiche. Toll. Also so hat
man früher gearbeitet, als man noch vernünftig gearbeitet hat.
Jetzt kann ich hier mal ein CD machen, nach vier gewinnt.
Das ist irgendwie hier, vier gewinnt, ein OAI.
So, und hier kann ich jetzt sagen, Java,
jetzt muss ich ganz kurz gucken, wie heißt denn das Ding hier?
Tippt, da ist es. Vier gewinnt Gui. Vier gewinnt Gui
. Ich kann da jetzt vier gewinnt Gui aufrufen. Und dann,
ich gebe also nur, dieses Java ist ein Kommando,
sozusagen im Betriebssystem aufrufen kann und sage,
hier ist jetzt mal eine Klasse mit einer Mainmethode, zack.
Und was passiert? Es klappt nicht. Exception in Thread Maine,
Java Lang, no such method error, Maine.
Gut, das heißt, was hier nicht geklappt hat,
ist, diese Klasse hat gar keine Mainmethode.
Nichts leichter als das. Ich schreibe jetzt hier mal so
eine solche Methode. Einfach mal live und in Farbe.
Public, Static, Void, Main, String,
Arx? So, diesen Parameter ignoriere ich mal,
weil den brauche ich ja jetzt gar nicht. Normalerweise kennt ihr das,
in Bluetay würde ich jetzt ein Exemplar von dieser Klasse erzeugen,
also mache ich das auch jetzt hier,
schreibe ich einfach nur hin, vier gewinnt Gui.
So, mal so übersehen, ob der euch das besetzen kann, kann ich übersetzen.
So, jetzt habe ich hier eine Main-Methode. Und jetzt,
oh Wunder, jetzt kann ich hier diesen Aufruf machen und
es wird hier gewinnt gestartet. Tatsächlich, aus dem Betriebssystem.
Also letztendlich ist Bluejay genauso irgendwie gestartet auf euren Windows-Rechner,
irgendwie über so einen Einstieg über diesen Punkt, über die Main-Methode.
Also auch Bluejay hat eine Main-Methode, wenn es selber gestartet wird.
Ja, das ist toll. Das ist nett zu sehen,
dass man das so machen kann. Wie gesagt,
man kann dann auch noch da jetzt Parameter angeben an der Stelle.
Ich kann also auch hier jetzt noch irgendwie sagen,
was weiß ich, irgendwas. Und die werden dann in
diesem Array mit übergeben. Haben wir jetzt hier nicht verwendet,
kann man aber sich dann in den Übungen,
könnt ihr euch das mal angucken.
Gut. Ach ja, was ich auch noch zeigen wollte.
Diese Methode kann ich auch hier einfach aufrufen. Da,
Main. Kannst einfach hier Main aufrufen. Dann ist das
genau so ein Aufruf. Also auch so ein Klassenobjekt,
kann man als ein Objekt ansehen, an dem man was aufrufen kann.
Also es ist tatsächlich sehr ähnlich. Zack,
da ist das wieder, das Vier gewinnt.
Großes Kino. Ja. Okay. Einstiegspunkt für Java,
Startknopf und so weiter. Dann habe ich jetzt gehört,
dass es in den Übungen mal so Fragen gab.
System Out, Printeln, was gisst denn das?
Das ist ja Magic, das verstehen wir gar nicht.
Das können wir gar nicht richtig benutzen. Gut, zugegeben
. Wir haben euch da was abverlangt,
was hart ist,
dass ihr
das so benutzen müsst
Es ist ja immer so diese Möglichkeit, etwas auf die Konsole rauszugeben.
Und auch das ist tatsächlich dann keine große Hexenkunst.
Das sieht ja so ein bisschen syntaktisch komisch aus,
weil hier sah irgendwie so ein Systempunkt outsteht.
Naja, und jetzt kann man sich das genau angucken.
Das ist nämlich eigentlich nichts weiter als die Klasse,
Java Legacystem, die hat eine öffentliche Klassenkonstante.
Und die heißt Out. Ich kann das mal zeigen.
Ich habe hier zufällig den Link auf die API von Java,
Class System, gehört zu Java Lang.
Könnt ihr euch also alles angucken.
The Clit the System Class Contain several useful class fields
and method
Not be instancyated. Das ist also eine Klasse,
von der es nicht mehr Exemplare gibt,
die ist nur dafür da, um als Klassenobjekt zu existieren.
Und da sieht man hier, oho, out ist ein Feld.
Das ist also ein öffentliches Feld,
aber immerhin ist es ein konstantes öffentliches Feld,
also eine, wenn man es ganz genau nimmt,
auf der Folie steht es auch drauf.
Es ist eine konstante Referenz auf ein Exemplar der Klasse Prince Stream.
Na gut, und Prince Stream,
wenn ich da jetzt draufklicke, dann sehe ich halt,
welche Operationen bietet denn Prince Stream.
Das ist irgendwie A Prince Stream Acts Functionality,
bla bla bla. Da kann man also irgendwelche Werte ausgeben
Und hier sind die ganzen Konstruktoren, da ist es nicht so viel,
aber man sieht jetzt hier ein Print, Print mit Bolien,
Print mit Char, Print mit Double, mit Float,
also es ist komplett überladen, also für jeden primitiven Typ gibt es hier einen Print.
Ja, und dann gibt es irgendwann auch nochmal einen Print F,
da gibt es einen Print LN, ja,
die ganzen Print LNs für die verschiedenen Typen, ja,
aber ihr seht, es gibt auch sowas wie ein Appent,
ich kann da auch eine Pent machen mit einem Char,
wer immer das tun will, ja,
kann man alles machen.
Also das ist also wirklich keine Echsenkunst,
es ist auch nichts weiter als ein, eine öffentliche Referenz,
die konstant ist und die verweist auf ein Objekt von Print
Und da kann ich zum Beispiel Printline mit einer Zeichenkette aufrufen.
Okay. Dann noch vielleicht so ein interessanter Aspekt.
Man kann Klassenobjekte auch initialisieren. Ihr wisst,
wenn ich ein Exemplar einer Klasse initialisieren will, dann macht man das,
wo sinnvollerweise, ruft es mir an den Kopf, im Konstruktor.
Genau, ein Konstruktor ist dafür da, um Objekte zu initialisieren, wunderbar.
Und beim Konstruktor von Objekten von Klassen ist es so,
dass man da auch Parameter angeben kann.
Das habt ihr gesehen, ja, Konstruktorparameter. Für diese
Klassenobjekte gibt es auch sowas wie Initialisierer, aber die sind nicht parametrisierbar.
Wer soll das auch aufrufen? Es ist tatsächlich so,
dass diese Klassenobjekte, die wir uns so vorstellen können,
die werden automatisch erzeugt, sobald ihr irgendwie Quelltext benutzt im laufenden System von einer Klasse,
mit sozusagen, dass der Classloader lädt die Klassen automatisch,
die benutzt werden.
Und dann hat man auch so ein Klassenobjekt. Das ist also
automatisch da und das kann man dann natürlich nicht parametrisieren.
Aber man kann eben halt tatsächlich Dinge initialisieren.
Ich kann also tatsächlich auch sagen,
in meiner Klasse Konto gibt es nicht am Anfang null Konten,
sondern es sind am Anfang 42. Wer immer das möchte,
kann dann auch tatsächlich in so einem Initialisierer Dafür sorgen,
dass die im Klassenvariablen auf einen sinnvollen Wert initialisiert werden.
Also das ist ein Klasseninitialisierer, der tatsächlich nur mit diesem Static eingeleitet wird.
Einfach nur Static und dann ein Blog und dann ist das sowas wie eine Initialisierung.
Für das Klassenobjekt. Ja, Klassenkonstanten habt ihr möglicherweise auch schon gesehen.
Das ist auch etwas, wo das Static drin vorkommt.
Also zum Beispiel sowas wie Public Static Final Int, Tage pro Woche.
Wir haben hier die Konvention und da sind wir auch inzwischen
, sagen wir, stabiler geworden.
Immer dann, wenn etwas wirklich Static Final ist,
also wirklich überall den gleichen Wert haben soll,
dann schreiben wir es in Großbuchstaben.
Also das sind so diese wirklich konstanten, konstanten.
Also es gibt ja auch noch so die Exemplarkonstanten,
wo jedes Exemplar zwar seine Konstante hat,
aber jedes Exemplar hat einen eigenen Wert für die Konstante.
Das hier sind richtige, echte Konstanten, die sind sozusagen
über alle klassengleich konstant. Also was wie Tage pro Woche,
Pi, Anzahl Spalten in irgendeiner Darstellung und so weiter.
Also wenn ihr solche Magic Numbers in Programmtexten seht,
dann solltet ihr immer gleich, sollte es eine Alarmblocke angehen,
also wenn da irgendwie mit Tagen irgendwie umgedreht wird,
da steht eine 7 im Quelltext.
Es ist eigentlich immer besser,
wenn man da eine Konstante verwendet,
dann ist einfach das
ein bisschen sprechender
Ja, genau. Also das ist durchaus schlau.
Solche Konstanten auch zu verwenden. Ja, dann hier nochmal
die Klassenoperation als Dienstleistung. Diese Folie habe ich eben schon
mal gesehen. Ich weiß nicht heute, was los ist.
Irgendwie sind da Folien verdoppelt. Das habe ich alles schon erzählt.
Nicht alle Objekte sind Exemplare. Das ist jetzt nochmal so
ein begrifflicher Punkt. Zum Schluss nochmal so ein bisschen so
ein kleines Bonbon. Wir haben ja bisher immer gesagt,
der Begriff Objekt und Exemplar, wir sind austauschbar.
Ja, wenn ihr wisst,
ihr könnt von einer Klasse beschnittlich viele Exemplare erzeugen,
dann könnte man
die Dinge auch Objekte nennen
Jetzt haben wir so was Besonderes, nämlich so ein Klassenobjekt.
Da möchten wir natürlich auch sagen können, dass es ein Objekt ist.
Deswegen sind ab sofort alle Dinge, die so einen Zustand haben,
den man sondieren kann und die Dienstleistungen anbieten, sind halt Objekte.
Das ist total objektorientiert. Aber nur die Objekte,
die man erzeugt durch einen Konstruktoraufruf, die nennen wir dann auch Exemplare.
Weil das sind dann Exemplare von Klassen. Das heißt also
Exemplare sind eine Untermenge von allen Objekten. Das ist nur so,
ja, so ein bisschen für die Genauigkeit,
weil es eben halt keine Die Möglichkeit gibt, ein Klassenobjekt zu erzeugen.
Es sind keine Exemplare von irgendwelchen Metaklassen. Das ist tatsächlich
in anderen Sprachen anders. In Smalltalk ist tatsächlich die Idee,
jedes Objekt ist ein Exemplar in der Klasse. Das heißt,
für so ein Klassenobjekt gibt es dann eine Metaklasse, die dann,
mit der man dann so dieses Ding irgendwie logisch erzeugen kann.
Die haben da also sozusagen sehr elegant so einen Abschluss gefunden.
In Eifel ist es komplett überhaupt nicht vorhanden.
Also Eifel ist eine Sprache, die für Archäologen der Informatik
noch eine Relevanz hat. Also da ist es so,
dass tatsächlich Klassen zur Laufzeit gar nicht mehr existieren.
Da sind Klassen nur so Beschreibungen von Klassen im Quelltext.
Und zur Laufzeit hat man nur noch Exemplare von Klassen.
Gibt auch noch eine ganz andere verrückte Sprache, so Forschungssprachen.
Da ist es so, da gibt es überhaupt gar keine Klassen mehr.
Da beschreibt man im Programmtext ein Objekt. Und wenn man
davon noch eins haben will, dann sagt man einfach Clone.
Das sind so exemplarbasierte Sprachen, Self, Sessel, ganz toll.
Wenn man da irgendwie in die Programmiersprachenforschung rein will,
dann sind das sehr, sehr spannende Sprachen.
Ja, dann gibt es hier noch so eine Darstellung,
wie das in der UML aussieht. Ihr seht hier,
wenn ich eine Klassenvariable oder eine Klassenmethode habe im UML,
L-Diagramm, in einem Klassendiagramm, dann ist das hier so unterstrichen.
Also Link hier, damit ihr seht,
das ist also die Stellen, an denen da das unterstrichen wird.
Da ist eine Frage. Danke für den Jahr,
was gebraucht ist ein Exemplar, was hier zu spart.
JavaScript ist tatsächlich eine exemplarbasierte Sprache. Klar, was Skript
ist eine andere Sprache, also hat nichts mit Java zu tun.
Wirklich ziemlich wenig. So, okay, ja,
das ist nochmal die Zusammenfassung. Also Klassen aufpassen,
sie können auch selbst wieder als Objekte angesehen werden.
Klassenmethoden können auch dann aufrufbar werden mit Static und es gibt öffentliche Klassenkonstanten.
So, und wir sind mit der Zeit ganz gut unterwegs.
Ich habe noch eine letzte Folie und wünsche euch fröhliche Weihnachten,
guten Rutsch und wir sehen uns im neuen Jahr wieder zu neuen Aufgaben.