Hallo, herzlich willkommen zur fünften Vorlesung.
Von SE1. Ich werde immer mal wieder mir die Freiheit nehmen,
so ein paar Worte vorneweg zu sagen.
Manchmal sind es mahnende Worte. Manchmal sind es auch
nur Informationen, die wir weitergeben. Die erste Information,
der zweite Teil des Skriptes, liegt jetzt im Komsi,
seit zwei Tagen schon, immerhin in digitaler Form.
Wir wollten es auch schon seit letztem Donnerstag in den Übungen verteilen,
damit ihr jetzt hier alle die Chance habt mit dem ausgedrückten Skript zu sitzen.
Hat nicht geklappt. Die Druckerei hat leider nicht so schnell
geliefert. Wir haben das eine Woche vorher in Druck gegeben
Hat halt zehn Tage gedauert und nicht sieben. So ist
das. Es gibt ja auch keine Garantien für sowas.
Es ist ein Dienstleister, ein Dienstleister,
wir nehmen den Dienst in Anspruch, wir sind die Klienten.
Ihr wisst ja, wie das ist in der Objektorientierung,
ist das ja ähnlich. Die ersten drei Aufgabenblätter sollten inzwischen abgenommen sein.
Wir haben jetzt gerade die vierte Übungswoche hinter uns,
das heißt eigentlich vernünftigerweise hat man alle vier Aufgabenblätter jetzt schon fertig.
Aber drei müssen jetzt abgenommen sein, weil sonst formal die Scheinbedingungen
nicht erfüllt sind. Ich hoffe, das ist allen bewusst.
Wir machen das schon relativ klar so, dass wir sagen,
kümmert euch rechtzeitig darum, die Aufgaben zu bearbeiten,
weil ihr sonst relativ schnell abgehängt werdet von den Inhalten,
die wir so vermitteln.
Dann, im Kommen sie, da hat Fred was gemailt,
dass ihr doch eure eingetragenen E-Mail-Adressen mal überprüfen solltet.
Ich habe hier mal das Mincom sie.
Da gibt es hier,
bitte überprüft eure hinterlegten E-Mail-Adressen
Ja, da gibt es also so ein paar E-Mail-Adressen,
die irgendwie falsch sind. Außerdem ist es so,
dass ihr nicht nur, wenn ihr eine falsche E-Mail-Adresse eingetragen habt,
die korrigieren solltet, das ist hilfreich,
damit wir euch über das Comsi erreichen können,
sondern auch diejenigen, die eine richtige Adresse hinterlegt haben,
diese aber nie lesen, sollten die auch ändern in eine E-Mail-Adresse,
die sie regelmäßig lesen.
Weil wir haben da ja irgendwie jetzt drei Kategorien von Adressen. Einmal so die Stine-Adressen,
die ihr irgendwie zentral kriegt, dann gibt es die Informatikadressen,
das sind die klassisch, die mit, was weiß ich,
Eins-Jährling oder so und gibt es solche hier,
irgendwie at web.de oder Hotmail oder was auch immer,
das ist alles immer ganz schrecklich.
Also wenn ihr da eine E-Mail-Adresse habt,
dann bitte guckt nochmal nach, welche ihr hinterlegt habt,
ihr könnt das ändern bei eurem Eintrag,
bei eurem Comsay-Account, sodass ihr da eine E-Mail,
deshalb habt, dass man euch auch erreichen kann.
Das wäre sehr hilfreich. Es gibt jetzt auch zwei Tutorien
und zwar einen am Mittwoch und eine am Donnerstag.
Fred bietet zwei Termine an, an denen hier,
wenn ihr ein bisschen das Gefühl habt,
ihr könnt noch ein bisschen Inhalte wiederholen wollen,
dann könnt ihr in das Tutorium gehen.
Könnt ihr leise sein? Ich habe das Gefühl,
dass wir da ganz schön viele Leute quatschen.
Ich glaube, ich habe das schon mal erklärt.
Das ist ganz einfach. Wenn ich hier vorne stehe,
da hatte ich eine Vorlesung, dann redet niemand anders.
Ich möchte jetzt nicht autoritär erscheinen, aber es wäre schon schön,
wenn ihr im Interesse der anderen Leute,
die zuhören wollen, nicht reden würdet.
Und da gibt es immer wieder Leute, die das betonen,
dass es schwierig ist, das hier zu verstehen.
Und es liegt nicht an mir, weil ich zu leise rede.
Vielen Dank. Gut. Zwei Futorien. Wie gesagt,
wer glaubt, die Inhalte nochmal wiederholen zu müssen
Oder zu wollen, kann das in den Tutorien machen.
In den Tutorien werden wir keine Abnahmen machen.
Also wenn jemand noch irgendwie Abnahmen nachhängen hat,
dann sind die Tutorien nicht der richtige Ort dafür.
Die Tutorien sind eine Möglichkeit, Inhalte zu wiederholen, Fragen zu stellen.
Da können auch mal, also Fred ist da sehr agil,
das heißt, er kann sehr leicht darauf reagieren,
was ihr für Fragen stellt, kann auch live irgendwas zeigen,
wird auch Blue Jay dabei haben und ähnliches.
Okay. Ja, bisherige Begriffe und Konzepte müssen nun sicher beherrschen.
Das ist wieder so eine nette Aussage. Wir haben,
um das mal zu verdeutlichen, jetzt vier Wochen hinter uns.
In diesen vier Wochen haben wir euch mit ziemlich vielen Begriffen zugeballert.
Also wir haben irgendwie erzählt, es gibt Klassen und von diesen Klassen kann man Exemplare erzeugen.
Die Exemplare zeigen ein Verhalten, das wird in den Methoden deutlich,
man kann die Methoden aufrufen, die haben einen Zustand,
in den Zustandsfeldern, die heißen auch Exemplarvariablen.
Man kann Methoden aufrufen, man kann Parameter übergeben,
da gibt es aktuelle Parameter und formale Parameter.
Es gibt sowas wie eine Sequenz, Anweisungsfolge, es gibt Ausdrücke,
es gibt die Syntax, ein EBNF, bedingte Anweisungen,
primitive Typen, das ganze Zeug, ganz schön viel Zeug.
Das Blöde ist, wir müssen euch das ein bisschen deutlich machen,
dass das wichtig ist, weil alles, was danach kommt,
und da kommen ja jetzt so die nächsten Levellichten sich langsam die Nebel,
der nächste Level steht an.
Heute fangen wir mit Level 2 an. Alles,
was da jetzt kommt, baut auf dem Zeug auf,
was wir euch schon erzählt haben.
Das ist wie so ein Lego-Baukasten und wenn ihr irgendwie das Fundament
nicht habt, dann ist das Ganze auf Sand gebaut.
Also ihr müsst leider diese Begriffe,
die wir euch hier beigebracht haben oder die wir euch vorgeführt haben,
die müsst ihr versuchen, alle zu verstehen und alle irgendwie in einen Kontext bringen zu können.
Das ist tatsächlich relativ viel Zeug. Für die,
die programmieren können, ist es möglicherweise,
man hat ein bisschen weniger Aufwand gewesen, für die,
die nicht programmieren konnten,
war es stellenweise
viel Arbeit
Das wird auch noch so weitergehen,
also auf jetzt Level 2 ist es für diejenigen,
die programmieren können, auch noch so,
die meisten Sachen haben sich schon mal wahrscheinlich woanders gehört.
Ab Level 3 wird es dann eher für die interessant,
die schon vorher mal was gemacht haben.
Ja, okay. Um euch noch eine weitere Hilfe zu geben,
noch mal Inhalte zu wiederholen auf eine etwas andere Art und Weise,
also nicht einfach nur trocken die Aufgabenblätter noch mal durchzugehen oder das Skript noch mal durchzulesen.
Das hilft übrigens auch sehr, kann ich so aus Erfahrung sagen,
dass man einfach mal ins Skript guckt und was da so steht,
weil auch nicht immer alles, was ich hier sage,
alles so erläutert.
Manche Sachen sind im Skript auch etwas ausführlicher, aber allerdings
nur wenige Sachen. Deswegen haben wir ein Spiel uns überlegt.
Und Janina Nehmetz, die bei mir Bachelorarbeiterin ist,
die will das im Rahmen ihrer Bachelorarbeit hier mal einführen.
Also SE1 sozusagen als guten Raum, um dieses Spiel auszuprobieren.
Das ist jetzt kein Shooter, kein Ego-Shooter, den wir
mit euch spielen. Das Spiel heißt Guess My Object.
Und das dient primär dazu, den Zusammenhang zwischen Schnittstelle und Implementation
zu verdeutlichen. Weil ihr habt ja schon gelernt,
es gibt irgendwie so eine Außensicht auf Objekte,
also was ein Klient sehen muss und wissen muss,
die Schnittstelle
Die Innensicht für jemanden, der an der Klasse vielleicht irgendwas schreiben will.
Und das ist eigentlich ein ganz einfaches Spiel, relativ simpel.
Es wird für jedes Spiel ist ein Blue Jay-Projekt vorgegeben.
Eigentlich in der ersten Stufe jetzt, was ich gleich zeigen werde,
sogar nur eine Klasse für jede Aufgabe.
Und da geht es darum, dass man rausfindet,
was die Klasse denn macht.
Warum muss man das rausfinden? Ich werde es mal vorführen
. Blue Jay kommt zu mir
Das ist jetzt mal so ein Beispiel. Wir haben also
die Aufgaben in drei Stufen eingeteilt. Das ist so der
erste Versuch, das mal so ein bisschen zu kategorisieren.
Leicht mittel und schwer. Und das sind also jetzt hier
sechs Klassen. Und ihr seht, da steht no source.
Das heißt, da ist kein Quelltext dabei.
Wenn ich jetzt hier einen Doppelklick mache, dann sagt der
Joe Blue Day hier, da ist kein Quelltext dabei.
Das Schöne ist, wir können das Zeug trotzdem benutzen.
Was hier fehlt, ist die Punkt Class-Datei, die Punkt Java-Datei,
also der Quelltext, das, was ihr lesen könnt.
Was aber da ist, ist die Punkt Class-Datei.
Also wir können es ausführen. Ich kann also hier ein
Exemplar erzeugen dieser Klasse. So, und jetzt kann ich
hier sehen, was gibt es denn da für eine Methode.
Die Schnittstelle ist relativ einfach. Es gibt eine Beispielmethode,
bekommt ein Int und liefert einen Bolien
So. Und das Spiel besteht jetzt darin, dass sie in
der ersten Stufe rausfindet, was macht das Ding denn?
Was macht denn so ein Objekt jetzt? So,
jetzt rufe ich das einfach mal auf. Ich meine,
wie soll ich das rausfinden, wenn ich es nicht ausprobiere?
Ich probiere es einfach mal aus. Ich gebe hier mal
eine Null ein. Dann kommt True zurück. Dann gebe ich
jetzt mal den nächsten Test, gebe ich mal eine Eins ein.
Kommt fort zurück. Okay, vielleicht hat jemand jetzt schon
eine Ahnung, wo es hingehen könnte.
Ich gebe eine 2 ein, kommt ein True raus.
Das ist jetzt eine leichte Aufgabe. Wir hatten eine Idee
, wie sich das Ding verhält
Ja, das ist vermutlich eine richtige Vermutung.
Ich habe es nicht selbst geschrieben, hat Janina geschrieben.
Das ist also hier eine Klasse, die hat keinen eigenen Zustand.
Es ist auch tatsächlich so, dass ihr,
also der Quelltext fehlt, ihr müsst es interaktiv benutzen.
Erste Aufgabe herausfinden, was die Klassen tun, die Objekte
der Klassen. Zweite Aufgabe, zweite Teil der Aufgabe,
ist deine eigene Implementation angeben, die sich genauso verhält.
Also sozusagen nachbauen, was da wohl gebaut ist.
Das muss nicht genauso sein. Es kann sein,
dass das gleiche Verhalten anders implementiert ist.
Aber es wird schon meistens in die Richtung gehen.
Schummeln ist verboten
Exemplare dürfen nicht mit dem Objektinspektor angesehen werden. Das ist
also genau das, was man jetzt hier machen könnte.
Ich kann jetzt hier einen Doppelklick machen, aber das Ding hat
gar keine Attribute. Braucht es ja auch nicht, ja.
Es entmittelt sein bootes Ergebnis ja nur auf Basis der Parameter.
Also es ist eine sehr einfache Klasse,
eine zustandslose Klasse, die Exemplare haben auch keinen Zustand.
Und auf der einfachen Stufe ist es hier tatsächlich so,
dass da die alle zustandslos sind, die Exemplare.
Okay, das ist eigentlich schon alles, das ist die Grundidee.
Wir haben, wie gesagt, drei Projekte angelegt, eins mit leichten,
Klassen eins mit Mittelleichen und eins mit schweren. Ja,
und wenn ihr wollt, könnt ihr das versuchen,
das mal auszuprobieren Und uns interessiert natürlich insbesondere,
ob es euch irgendwas hilft, ob es irgendwie Spaß macht,
ob es hilft, ob es irgendwie das Verständnis vertieft.
Das wird alles interessant sein im Rahmen dieses Spiels.
Es ist überhaupt keine Verpflichtung, es ist ein Angebot,
wer es machen will, kann es gerne machen.
Und Janina steht dann auch für alle weiteren Fragen zur Verfügung.
Sie hat auch im Kommen sie einen Eintrag gemacht.
Also hier unter Diskussionen steht dann auch mehr dazu.
Guess my object, von Janina hier eingerichtet. Und da
sind dann diese Taktdaten, da sind auch die Spielregeln.
Also es gibt dann hier ein PDF, da sind die Spielregeln
nochmal genau abgelegt. Wie gesagt, das ist ein Angebot.
Es könnt ihr euch helfen, wenn ihr Schwierigkeiten habt,
das nochmal auf eine andere Art und Weise zu betrachten, die Inhalte.
Wir werden sehen, wie gut das funktioniert. Es wird natürlich
auch dann möglich sein, dass ihr selber vielleicht sagt,
oh, ich finde das Spiel irgendwie interessant.
Ich stelle jetzt mal eigene Aufgaben rein, könnt ihr auch machen.
Im Rahmen dieser Diskussion ist das dann möglich.
Also wir werden einfach mal sehen, wie gut das funktioniert.
Wenn es nicht funktioniert, dann war es das.
Genau. Okay. Ach ja.
Apropos Spiel
Ich mache noch mal ein Projekt auf hier. Ich weiß nicht,
ob ihr es schon wusstet, aber ich bin ungeschlagener Meister.
Im Vorlesungs-Tic-Tac-Toe. Ich spiele jetzt gegen euch Tic-Tac-Toe und mal
sehen, ob ihr eine Chance habt.
Also ich setze mal hier ein X hin,
ihr kennt Tic-Tac-Toe, man kann da irgendwo jetzt was hinsetzen,
ihr müsst mir jetzt zurufen,
wo ich eure Null hinsetzen soll
Oben rechts, oben rechts, ich habe oben rechts gehört, okay?
Okay. Dann setze ich jetzt hier mal meinen X hin.
Okay, wo soll ich jetzt was hinsetzen?
Links, Mitte, Linksmitte, okay.
Dann setze ich jetzt mal hier was hin. Oben bitte
. Was war das? Ich habe das nicht verstanden.
Unten, unten links. Ich habe gewonnen. Seht ihr
so einfach ist das? Es ist jedes Jahr das Gleiche.
Ich gewinne immer.
Das ist TikTok-Toe, das könnt ihr tatsächlich dann diese Woche in den Übungen auch spielen.
Wenn ihr es denn fertig implementiert, das,
was wir euch in den Übungen diese Woche geben, ist ein unvollständiges TikTok-Toe.
Und insbesondere in dieser Klasse werdet ihr arbeiten in dieser Woche.
Dieses hier ist nur eine Gui-Klasse,
die das Ganze visualisiert, die sich also darum kümmert,
dass wir hier so eine nette Gui haben.
Gui, werden wir erst im zweiten Semester thematisieren, ist erstmal nicht wichtig.
Was wir auch vorgeben, ist das Spielfeld.
Also es gibt hier sozusagen Klassen, die das Spielfeld darstellen.
Und hier ist es zum Beispiel so gemeint,
ein Spielfeld, ein TikTok-Toe-Spielfeld, besteht aus mehreren Spielfeldzeilen.
Und jede Zeile hat drei Zellen
Das heißt also, was wir hier dann schon sehen,
ist, diese Klasse benutzt diese Klasse über eine Referenz.
Und das sehen wir uns heute in der Vorlesung als erstes an.
Bis zur Pause werde ich jetzt über Referenzen reden.
Ich habe schon angekündigt, Referenzen sind der zentrale Mechanismus in Java.
Und den solltet ihr sehr gut kennen,
weil ihr sonst vermutlich nicht wirklich vernünftig arbeiten könnt.
Also, wir gucken uns das Typkonzept von Imperativen und
auch objektnotierten
Programmiersprachen an
Ihr habt schon gesehen, numerische Typen,
also elementare Datentypen für numerische und logische Probleme.
Die haben wir in der letzten Vorlesungswoche ein bisschen uns angesehen.
Und jetzt geht es um Benutzer-definierte Typen. Das ist also eine ganz spezieller Zusammenhang,
der gerade in der Objektorientierung sehr, sehr eigen ist.
Und das sollten wir uns sehr gut ansehen.
Ja, was ist denn ein Typ?
Ich habe es in der letzten Woche, glaube ich,
auch schon mal angesehen. Der Typbegriff ist ziemlich wichtig.
Und das ist hier mal die Definition aus dem Informatik-Duden.
Unter einem Datentyp versteht man
die Zusammenfassung von Wertebereichen
Und Operationen zu einer Einheit. Das heißt,
wenn wir sowas haben wie Int, dann ist nicht nur wichtig,
dass es eine Menge gibt von Zahlen, die zum Wertebereich von Int gehören,
sondern die ganzen Operationen gehören auch dazu. Also,
wenn ich hier unten sehe,
es gibt einen Wertebereich von circa minus zwei Milliarden bis plus zwei Milliarden,
dann ist das der eine Teil des Datentyps Int,
aber die Operationen sind halt auch wichtig, also Adian,
Subtrah hier, multiplizieren, ganz zahlige Divisionen,
immer nochmal in Erinnerung rufen,
ganz zahlige Divisionen,
ist was anderes als die Division mit Gleitkommazahlen
Oder den Datentyp Bul. Das ist ein völlig anderer Datentyp,
der besteht nämlich nur aus zwei Werten.
Es gibt nur die beiden Werte wahr und falsch.
Und dann gibt es verschiedene Operationen, um diese Werte miteinander zu verknüpfen.
Das habt ihr mit der Ampel zum Beispiel schon gemerkt.
Es gibt also einen und und es gibt einen oder und ähnliches.
Das sind jetzt zwei Beispiele für primitive Typen.
Warum hat man sowas überhaupt? Warum hat man einen Typen?
Was soll der Kram? Das ist ja eigentlich ziemlich albern,
dass man da irgendwie immer so viel hinschreiben muss.
Es gibt so Puristen in der Programmierung,
auch in der Objektantäre Programmierung, die sagen,
ich brauche da nicht an eine Variable ranzuschreiben,
was für einen Typ die hat.
Das ist lästig
Diese Schreiberei. Smalltalk zum Beispiel ist eine Sprache, die nicht erfordert,
dass ihr bei einer Variablen dran schreibt, welchen Typ sie hat.
Da könnt ihr an einer Variablen eine beliebige Referenz auf ein beliebiges Objekt zuweisen.
Das hat aber gewisse Vorteile, wenn man diese Typinformationen ranschreiben muss.
Ich habe das schon gesehen, wenn ihr eine Intvariable deklariert,
dann wisst ihr, da kann ich jetzt nur Instren abspeichern.
Also hier unten ist so ein Beispiel,
ich habe hier eine Variable Summ,
die ist vom Typ Int und da kann ich natürlich 12 plus 6 zuweisen,
weil 12 plus 6 für sich genommen ist ja ein Int-Ausdruck.
Das können wir uns auch
nochmal angucken
Ihr kennt schon die Direkteingabe. Die Direkteingabe ist super geeignet,
um sich mit Ausdrücken zu beschäftigen. Ich habe ja immer schon gesagt,
bei einem Ausdruck sieht man einfach, welchen Typ er hat.
Also wenn ich zum Beispiel jetzt hierhin schreibe,
was steht hier auf der Folie, 12 plus 6,
12 plus 6, dann rechnet er es nicht nur aus,
sondern er sagt mir auch, das ist übrigens vom Typ Int.
Also ein Ausdruck im Java-Quelltext,
jeder Ausdruck hat einen Typ und den kann der Compiler ableiten.
Und dann kann der Compiler natürlich auch Fehlermeldungen ausbruchen, wenn man was Falsches probiert.
Also wenn ich jetzt hier zum Beispiel sage, Intresult,
das war gleich 12 plus Falls sein, dann ist das einfach ein Typfehler.
Also es stand ein 12 plus Falls ist falsch,
also 12 plus False wird nicht funktionieren.
Operator Plus, can not be applied to intbullian.
Ich kann nicht einen Int und einen Budi miteinander mit Plus verknüpfen.
Das ist natürlich dann nützlich, weil dann mache ich bestimmte Fehler,
die man mal so nebenbei hinschreibt, mache ich dann vielleicht.
Da werde ich zumindest darauf hingewiesen vom Compiler.
Das ist eine Eigenschaft von statisch-typisierten Sprachen,
also so Sprachen wie Java, C. Sharp,
C. Plus, die prüfen das tatsächlich zur Übersetzungszeit.
Da muss man eben halt bei jeder Variante dranschreiben,
aber damit kann eben halt auch geprüft werden.
Das ist ganz nützlich
Eine zweite Motivation für Typisierung,
die man sich auch eigentlich klar machen sollte, ist,
wir haben ja schon drüber gesprochen, das Ganze,
die ganze imperative Programmierung läuft auf dem von Neumann-Rechner.
Also die ganzen Rechner, die wir so kennen,
sind letztendlich nach dem Prinzip der von Neumann-Architektur gebaut.
Also ein Hauptspeicher, dann irgendwie hier die CPU mit
einem Leitwerk und einem Rechenwerk und einem ein Ausgabewerk.
Und dieser Hauptspeicher ist üblicherweise in Zellen gleicher Größe unterteilt.
Die sind durchgehend adressierbar und die Maschine benutzt Binärcodes zur Darstellung
von Programmen und Daten. Also unsere Programme, wenn wir übersetzen,
sind ja dann im Binärformat im Rechner oder auf abgelegt.
Also hier haben wir zum Beispiel mal irgendwie einen Hauptspeicher mit
irgendwelchen Worten, viele Worte, die da drin stehen.
Und dann haben wir hier Daten und dann haben wir hier Programme.
Und das sieht einfach so aus. Auch das ist nur
ein Modell, das wir haben. Natürlich stehen da keine
Nullen und Einsen drin. Es sind irgendwelche elektronischen Zustandszustände,
die gehalten werden in elektronischen Bauteilen, die dann interpretiert werden als Null oder Eins.
So, und wenn ich jetzt auch so ein Wort drauf gucke,
wie hier 01, 0001, 11, 1,
was bedeutet das denn?
Dann sage ich, das hat überhaupt keine Bedeutung.
Das sind einfach nur Nullen und Einsen. Die Bedeutung kriegt Etwas,
was im Speicher steht, dadurch,
dass ich es mit einer bestimmten Brille ansehe.
Deswegen auch die Brille auf der vorigen Folie. Ich gucke darauf
und sage, das möchte ich jetzt als eine ganze Zahl interpretieren.
Dann kann ich da irgendwie die Stelligkeiten der Bits
irgendwie aufaddieren und komme dann zu irgendeiner ganzen Zahl.
Ich kann aber auch sagen, ich möchte das als eine Gleitkammerzahl interpretieren.
Das ist eine völlig andere Logik, wie die Bits interpretiert werden.
Ich schaue einfach drauf und interpretiere es. Und ich kann
genauso auch sagen, das soll ein Befehl sein,
naja, was ist das für ein Befehl hier?
Naja, ich muss halt irgendwie eine Abbildung machen.
Ich muss mir also überlegen, was ich sehen will und
das sehe ich dann auch.
Das ist auch so eine Interpretationssache. Das ist eben genau
die Idee von Typen
So, jetzt, wenn du mal so ein bisschen
einen kurzen Ausflug machen in den Hintergrund von,
vom Typbegriff, da wird auch gerne von Datentypen gesprochen.
Also die Idee ist dann, dass es tatsächlich zu jedem Wert,
dass jeder Wert zu genau einem Datentyp gehört.
Und dass es eben halt Operationen gibt.
Eine Wertemenge plus Operationen. Ihr habt auch schon festgestellt,
ihr müsst in Java immer eure Variablen deklarieren. Und all das,
was man so jetzt in Java und auch CPlus in anderen Sprachen macht,
das basiert eigentlich darauf,
was ein gewisser Herr Horr schon vor etlicher Zeit mal geschrieben
hat über solche Typisierungen und Programmiersprachen.
Und das gucken wir uns jetzt einfach mal an
Nicht erschrecken, Englisch. Ich hoffe,
das ist für die meisten von euch jetzt nicht zu lästig,
dass wir das mal machen. Das ist tatsächlich etwas,
was eher in einem Original-Paper 1972 da geschrieben hat.
Und da hat er versucht zu erklären, was ein Typ ist.
Und wir haben hier sozusagen die Übersetzung dessen.
Also ein Typ definiert eine Menge an Werten,
die eine Variable oder einen Ausdruck annehmen kann.
Klar. Eine Wertemenge, habe ich ja schon gesagt.
Dann, jeder Wert gehört genau zu einem Typ.
Das habe ich auch schon gezeigt. Ich habe das ja
mal hier in BlueJain-Eddeckt-Angabe gezeigt. Irgendwie null ist eben halt
ein Int und 0.0 ist ein Double
Und 0.0F ist ein Float. Das ist also tatsächlich
jeder Wert gehört zu irgendeinem Typ oder auch Falls,
ist ein Buli. Jeder Wert gehört zu irgendeinem Typ.
Typinformation ist statisch aus dem Quelltext ermittelbar. Also ich kann
es wirklich sehen und das ist wirklich nützlich. Auch ihr,
wenn ihr drauf guckt, könnt immer sofort sehen,
ah ja, da wird irgendwie ein Inten mit dem anderen addiert.
Also ist der gesamte Ausdruck auch ein Int. Und wenn
da jetzt aber noch wieder ein Float dazu addiert wird,
dann ist das Endergebnis dann wieder ein Float zum Beispiel
Operatoren sind auch getypt. Auch das habt ihr gesehen.
Also wenn wir hier jetzt mal schreiben, 3 plus 5,
dann ist es die ganz zahlige Addition. Wenn ich schreibe,
Axel plus doof, dann kommt da Axel doof raus.
Okay, also ich kann auch den Plus-Operator, er hat auch eine Pypisierung.
Ich habe auch eben gesehen, irgendwie 3 plus falls geht nicht.
Also auch dieser Operator hat eine Typisierung.
Er sagt genau, welche Operanten er
da zugreifen kann
Ein Typ definiert Operation, das ist das Zweite,
da oben fett, Wertemenge, da unten fett Operationen,
also merkt euch, ein Typ ist eine Wertemenge und Operationen drauf.
Warum macht man das? Naja, Typinformation schützt zum einen,
liegt aber auch die Semantik fest. Also es ist einfach
klar, was man mit den Dingern machen kann.
Es schützt einen vor Fehlern, aber es zeigt einem auch,
was möglich ist. Man kann dann nachlesen,
welche Operationen zum Beispiel für einen Datentyp verfügbar sind.
Und dann sagt er was, was war Anfang der 70er,
wir sind primär daran interessiert, was auch Mathematiker interessiert,
also Kathese Produkte, Mengen, Funktionen.
Das war eine sehr mathematisch geprägte Sicht auf die Informatik.
Die war damals sehr, sehr en vogue.
Deswegen habe ich hier reingeschrieben, die guten alten 70er Jahre.
Heutzutage sind wir da deutlich weiter. Es gibt auch eine
ganze Menge andere Dinge, die man modellieren möchte in Programmiersprachen,
die nicht unbedingt formal mathematisch beschreibbar sind.
Und die möchte man trotzdem programmieren können.
Also so diverse Spiele, die ihr so spielt,
sind vermutlich nicht in einem mathematischen Modell beschrieben.
Ist einfach so. Okay. Jetzt haben wir
schon letzte Woche die elementaren Typen kennengelernt
Ich habe gesagt, es gibt in Java acht primitive Typen.
Das sind genau acht, das ist festgelegt,
also int und Bulien und Float und Double und was weiß ich.
Und wir wollen aber ja, wenn wir letztendlich programmieren,
wollen wir ja irgendwie Probleme lösen. Das heißt,
wir bilden irgendwie Elemente aus der realen Welt,
real immer in Anführungsstrichen, die wir modellieren wollen,
ab in das Computersystem.
Das heißt, wir wollen sie irgendwie beschreibbar machen.
Ihr habt das schon gesehen mit dem Konto.
Wir haben ein Konto in einer Bankanwendung,
also definieren wir eine Klasse Konto.
Das ist ja auch
ganz schön
Die fundamentale Frage für Programmiersprachen ist, macht man so was,
indem man in der Programmiersprache die ganzen Dinger schon zur Verfügung stellt?
Man könnte ja sagen, wir haben eine Programmiersprache,
die ist für Banken nützlich. Da kann man eben halt
so Kontonummern und Konten und alles schon modellieren.
Ist schon da. Diese Datentypen sind schon da.
Das ist tatsächlich der Ansatz gewesen von PL1 in den 60ern
oder auch von Cobol für kaufmännische Anwendung.
Dass Dinge, die man in solchen Kontexten braucht,
in der Sprache fest eingebaut sind.
Und das ist deswegen sehr gut zu dem Anwendungsbereich passt.
Das Dumme ist halt, seit den 60er Jahren haben sich
die Breite der Anwendungsmöglichkeiten für Computer enorm vervielfacht ist.
Man kann inzwischen Computer fast überall einsetzen und entsprechend hätte man
da irgendwie eine ganze Menge an Programmiersparen.
Deswegen war ein anderer Ansatz und der hat sich eigentlich durchgesetzt in modieren mit modernen Programmiersprachen.
Wir haben einen Basissatz an Typen und dann bieten wir in
der Sprache Möglichkeiten, neue Typen zu bauen.
Also neue Benutzer definierte Typen. Und wenn ihr jetzt da
das Konto zum Beispiel mal benutzt habt,
dann habt ihr bisher nur wahrgenommen,
naja es ist eine Klasse,
davon kann ich Exemplare erzeugen,
aber das ist auch ein Typ und das gucken wir uns
jetzt ein bisschen näher an
Das heißt, was ihr bisher gesehen habt, waren Klassen,
die wir mit euch in den Übungen gebaut haben,
die ihr in den Übungen gebaut habt, die hatten irgendwelche Zustände,
aber diese Zustände waren definiert über primitive Typen.
Wir haben explizit dafür gesorgt, dass ihr nur Klassen baut,
die in ihren Exemplarvariablen aus primitiven Typen bestehen.
Also ein Konto hat ein Saldo,
die Ampel hat irgendwie mehrere Bullyens gehabt,
die Waage hat das irgendwie das Gewicht gehalten und ähnliches.
Also relativ einfach. Was jetzt durch das,
was ich erzählte, was ich jetzt hier vorstellen will,
über Referenzen möglich wird,
ist,
dass wir Objektgeschlechte bauen
Objekte verknüpfen miteinander, dass ich sagen kann,
ein Objekt besteht nicht nur in seinem Zustand aus primitiven Typen.
Das Interessante ist auch übrigens, wenn man eine Klasse hat,
die Exemplarvariablen, wo die nur von primitiven Typen sind,
da ist die mögliche Menge der Zustände relativ klar beschrieben.
Also wenn jetzt zum Beispiel die Ampel euch anguckt,
die hat drei bulsche Variablen, wie viele verschiedene Zustände,
also ganz technisch einfach betrachtet,
kann denn so ein Exemplar einer solchen Ampel dann haben bei
drei bulschen Variablen.
Wie viele verschiedene Zustände kann es geben
Acht. Richtige Antwort. Weil es gibt für den
ersten Buhl zwei Möglichkeiten, True and Falls.
Für jede dieser Möglichkeiten gibt es wieder für die nächste zwei Möglichkeiten.
True do Forts und dann, ja,
also es ist zwei hoch drei, ist also acht Möglichkeiten.
Das ist also tatsächlich ganz klar definiert. Bei primitiven Typen,
wenn das nur aus primitiven Typen besteht, die Exemplarvariablen.
Wir gucken uns jetzt was anderes an, nämlich Exemplarvariablen,
die von einem Klassentyp sind. Und dann entstehen genau solche Objektgeflechte,
dass man sozusagen Objekte miteinander über Referenzen verknüpft. Und das ist etwas,
das nicht nur bei uns in einem Erfahrungshorizont liegt,
sondern allgemein auch in der Literatur über Programmierausbildung.
Referenzen sind schwierig. Referenzen sind etwas, was viele Programmieranfänger fordert.
Und das liegt daran, dass da irgendwie eine Indirektion drin ist.
Und diese Indirektion werde ich jetzt erläutern. Okay. Also,
wenn ich irgendein Objekt benutzen will in Java,
dann brauche ich eine Referenz. Eine Referenz ist, ja,
wir haben ein Verweis, ein Zeiger, ein Pointer.
Ich habe hier auch mal versucht, das anzudeuten mit so einer Drachenschnur.
Ich muss irgendwie irgendwas in der Hand halten,
das mich mit dem Objekt verbindet.
Ich muss da irgendwie hinkommen zu dem Objekt
Wenn ich irgendein Objekt erzeuge, also ein Dienstleisterobjekt,
dann wird da immer eine Referenz geliefert.
Und diese Referenz wird auch tatsächlich als ein Wert behandelt.
Das mag jetzt erst mal komisch sein.
Und dann haben wir Referenzvarianten. Ich zeige das jetzt mal,
wie das bisher ist, was ihr bisher kennt.
Das waren diese einfachen Variablen. Also sowas wie in Antwort.
Das ist eine Variable, die heißt Antwort, ist vom Typ in.
Und dann irgendwie ist da auch mit verbunden,
dass es da einen Speicherplatz gibt, wo dann die entsprechenden Werte drin abgelegt werden können.
Also mache ich eine Zuweisung, weil es dem 42 zu,
dann steht die 42 quasi in diesem Behälter drin
Variable muss deklariert werden, Name als Bezeichner,
muss ein Typ angegeben werden und ich kann da Werte drin ablegen.
Das ist etwas, was ihr jetzt schon auf verschiedenen Ebenen mal gesehen habt.
Das ist etwas anders hier. Jetzt haben wir imperative Referenzvariablen.
Das heißt, was wir da haben, ist zweierlei.
Wir haben zum einen diese Referenzvariable, die ist auch wieder
ein Behälter und in diesem Behälter steht was drin.
Aber in dem Behälter steht nicht das Objekt selbst drin,
sondern es steht da nur, ja, so eine Referenz drin.
Also irgendwie so ein Ding, dass dann auch das Objekt zeigt,
oder verweist oder damit dranhängt. Ich habe hier nochmal ein Projekt,
das ihr ja auch schon kennt, die Zeichnung.
Und da habt ihr ja hier den Zeichner. Vielleicht erinnert euch
da noch dran, das war diese Sache mit dem Zeichner.
Und man konnte da jetzt irgendwie Zeichner aufrufen als Klient.
Ich kann hier Interaktivzeichner aufrufen. Und dann wird hier in
dieser Methode werden dann mehrere Objekte erzeugt.
Und was wir jetzt hier sehen, ist,
das hier ist eine Variable vom Typ Wand, von vom Typ Quadrat.
Und diese Variable ist eine Referenz variable. Und ich,
dieser Stelle weise ich dieser Referenzvariablen etwas zu, nämlich eine Referenz.
Und das, wo kriege ich die Referenz her von diesem Aufruf?
Das hier ist ein Konstruktoraufruf. Habt ihr jetzt hoffentlich auch
schon mehrfach gesehen. Mit New Quadrat erzeuge ich ein Objekt.
Das Objekt wird irgendwo im Speicher erzeugt. Wir wissen nicht
so genau wo. Und wir kriegen eine Referenz da drauf.
Irgendwie ein Handel, eine Verbindung. Und dieses Ding speichern
wir hier in der variablen Wand. Also das ist die
Veranschaulichung von dem, was hier auf der Folie ist.
Das hier ist die variable Wand. Und da drin ist
eine Referenz auf ein Objekt
Das ist was anderes als bei den normalen, inprimitiven Typen.
Da steht das Ding, was man da speichert, direkt da drin.
Da steht der Wert wirklich in der Variablen drin.
Hier steht aber kein Objekt drin. So,
das ist tatsächlich hier ein Effekt, der ganz spannend ist.
Und eine Referenzvariable hat auch wieder einen Typ, nämlich ein Referenztyp.
Das heißt also, dieser Typ Quadrat ist ein Referenztyp.
Und es ist einfach so, jede Klasse in Java
definiert einen Referenztyp
Ich kann also den Namen einer Klasse,
den ihr selbst geschrieben habt, die ihr selbstständigt,
kann ich als Typ in einer variablen Deklaration verwenden.
Konto, ein Konto. Oder wie hier, Quadratwand.
Der Name der Variablen, der Typ,
das ist ein Referenztyp, also ist das eine Referenzvariable.
Okay. Und da ist es halt genauso, ich kann erstmal
die Variable deklarieren, dann zeigt die erst mal auf Nüscht.
Und dann kann ich da etwas zuweisen, dann enthält diese
Variable eine Referenz. Okay, ich will jetzt nochmal so
ein paar Dinge zeigen an diesem Ding hier mit dieser Wand.
Wenn ich zum Beispiel jetzt hier, Einfach mal das nicht hinschreibe.
Also wir machen es mal anders, ich mache es mal anders.
Ich kommentiere das aus. Dann ist es so,
die variable Wand ist hier deklariert, aber sie ist nicht initialisiert.
Das heißt, da steht nichts drin. Diese Variable ist
einfach leer. Da steht also keine Referenz auf ein Objekt
drin. Dann wird dieser Aufruf hier fehlschlagen.
Dann versuche ich nämlich über diese Referenz zu dem Objekt
zu kommen und an dem Objekt jetzt
diese Operation Farbe ändern aufzurufen
Ich kann das jetzt mal übersetzen. Ja, dann warnt mich der Compiler.
Das ist schon mal gut. Wir haben wieder eine Typisierung.
Der Compiler kann mir also jetzt helfen und kann sagen,
hey, du hast Wand noch gar nicht initialisiert.
Wieso willst du es denn schon benutzen?
Das ist super. Also müssen wir den Compiler austricksen.
Ich mache jetzt einfach mal Folgendes. Ich schreibe hier Nall
hin. Nall heißt so viel wie, kein Objekt ist
mit diesem Ding verbunden. Damit sage ich jetzt explizit,
ich möchte, dass da Nall drin steht,
dass diese Variable mit keinem Objekt verbunden ist.
Das müsste der Compiler jetzt schlucken
Das übersetze, dann nimmt er es auch an.
Aber jetzt kann ich hier den Zeichner aufrufen und sagen,
mach doch mal, zeichne doch mal was.
Und dann sage ich jetzt hier irgendwie, was weiß ich,
gelb, ist ja auch wurscht, gelb.
Und dann kracht es. Java Lang Null Pointer Acception.
Weil an dieser Stelle versucht wurde, über diese Variable
eine Operation aufzurufen, aber da steckt kein Objekt dahinter.
Das ist tatsächlich genau diese Situation, die hier auf der Folie
angedeutet ist, hier enthält das Ding einfach noch nichts.
Da ist eine Frage
Und nimm alles. Wie nimmt man denn alle Objekte?
Also bisher habt ihr gelernt,
mit einem Konstrukteaufruf kriege ich eine Referenz auf ein Objekt.
Und diese Referenz kann ich ablegen in einer Variablen,
um dann im folgenden über diese Variable Operationen aufzurufen.
Es gibt keinen Pool von allen Objekten,
wo ihr irgendwie Referenzen kriegen könnt.
Ihr könnt Referenzen momentan nur kriegen, durch Konstrukteaufrufe.
Ich werde gleich nochmal darauf eingehen, wie man sie noch kriegen kann.
Okay, gehen wir erstmal weiter.
Dann kann ich vielleicht nochmal das eine oder andere zeigen
Ich habe ja schon gesagt, ein Typ Wertemenge plus Operationen.
Das ist jetzt bei diesen Referenztypen genauso. Die sind auch
solche Typen. Das heißt, ich habe erstmal alle Exemplare
einer Klasse, die gehören zur Wertemenge des Typs.
Also klasse Konto, alle Exemplare, der klassische Konto,
sind Elemente in der Wertemenge. Das heißt, diese Wertemenge
ist auch beliebig groß und die ist auch ziemlich dynamisch.
Mal sind mehr Elemente drin, mal weniger, weil so
ein Objekt kann ja erzeugt werden, kann auch wieder verschwinden.
Das ist also etwas anderes als bei Int. Bei Int
ist es klar definiert. Ungefähr vier Milliarden Werte oder bei Genau zwei.
Da ist die Wettemenge ganz fest. Das ist hier bei
den Referenztypen ein bisschen anders. Und die Operationen,
die man auf so einem, auf so einer Referenzvariablen ausführen kann,
sind natürlich genau die Methoden, die die Klasse anbietet.
Das ist auch nochmal hier schön zu sehen, wenn ich,
hier ist nochmal die Konsole, auch sehr schön.
Wenn ich hier mir jetzt mal angucke,
was ich hier aufrufen kann, dann sieht man hier zwei Methoden.
Zeichne und zeichne Häuser. Das sind die Operationen,
die ein Klient der Klasse Zeichner aufrufen kann.
Die gehören zur Schnittstelle und sind damit Operationen des Typs
Wenn wir jetzt mal reingucken in die Klasse Zeichner,
dann sehen wir, dass da ja noch mehr Methoden sind.
Hier ist eine weitere Methode Public und dann kommen aber hier
private Methoden. Diese privaten Methoden gehören nicht zur Schnittstelle
und sind damit auch keine Operationen des Typs. Also,
ein Compiler kann bei der Übersetzung anhand des Typs einer Referenzwahl im Programmtext
erkennen, welche Operation an dieser Variablen zugelassen sind.
Das kann ich auch zeigen, indem ich jetzt einfach mal hier was ganz Wirres mache.
Ich sage zum Beispiel, Das lässt sich ja übersetzen.
Ihr habt gesehen, das lässt sich übersetzen.
Das ist jetzt zwar, es führt dann bei der Laufzeitzone
ein Problem. Ich kann jetzt mal schreiben, wann.drehen.
Super. Ich habe mir gerade überlegt, so eine Wand
, so ein Quadrat muss man auch irgendwie drehen können.
Super Idee. Ich als Klient denke mir, super,
ich möchte jetzt diese Dienstleistung haben. Ja,
aber die Operationen, die der Typ anbietet, sind natürlich festgelegt.
Es gibt eben halt genau die öffentlichen Methoden der Klasse Quadrat
, die kann ich aufrufen.
Die gehören zu den Operationen, die ich ausüben kann.
Drehen wird nicht gehen. Der Compiler meckert. Er sagt
, cannot find simil, Method drehen.
Gibt es nicht
Auch das wieder, es nützt uns,
wenn wir da so ein bisschen Feedback vom Compiler kriegen.
Und das zur Übersetzungszeit und nicht erst, wenn das Programm läuft.
Okay. So, und das ist tatsächlich so ein Zusammenhang,
da sind Ähnlichkeiten da zwischen diesen Typen,
also zwischen den primitiven Typen, Wertemenge und Operationen und den Referenztypen.
Alle Exemplare eines Dings, die erzeugt wurden,
plus die Methoden, die öffentlichen, die ich aufrufen kann.
Das bildet zusammen auch wieder einen Typ.
Das ist in vielerlei Hinsicht sehr ähnlich. Das heißt also,
es besteht ein direkter Zusammenhang zwischen der Schnittstelle eines Objektes und
seinem Typ
Also auf Stufe 1 haben wir ja gelernt,
die öffentlichen Methoden einer Klasse definieren die Schnittstelle.
Und eine Klasse definiert auch einen Typ, ein Referenztyp.
Wir können Referenzvariabel dieses Typs deklarieren. Das heißt,
die Operationen sind genau die öffentlichen Methoden. Das ist genau
dieser Zusammenhang, den ich eben versucht habe anzudeuten.
Tatsächlich ist da das sehr eng zusammenhängend. So, jetzt
mal so ein paar technische Sachen zu den Referenzen in Java.
Wenn ihr irgendein Objekt in Java manipulieren wollt, braucht ihr
eine Referenz.
Es geht nicht ohne
Der Witz ist, wenn ihr eine Referenz bekommt,
dann wird die tatsächlich auch kopiert. Ich kann das vielleicht mal zeigen,
indem ich hier einfach mal einen zweiten Parameter einführe.
Quadrat Kuh. Ich sage jetzt einfach,
ich möchte das hier ein Quadrat übergeben wird.
Das geht genauso. Das ist ein Typ wie jeder andere.
Also diese selbstdefinierten Typen sind auch alle ganz normale Typen.
Also genau wie eins dringen oder ein Int,
kann ich auch ein Quadrat übergeben.
Das heißt, an dieser Stelle sage ich jetzt einfach mal,
Wand ist gleich Kuh
So, was wird denn da jetzt übergeben? Naja,
wir wissen ja, dass das Quadrat Q da oben,
das ist ein formaler Parameter.
Dieser formale Parameter ist ein Referenztyp, also wird da eine Referenz übergeben.
Es wird nicht das Objekt Quadrat übergeben, irgendein Quadratobjekt,
sondern nur eine Referenz auf ein solches Objekt.
Das kann ich jetzt übersetzen. Ja, natürlich muss ich
mal dieses Drehen da wieder rausschmeißen. Das ist ja Quatsch
. So, lässt sich übersetzen. Und jetzt kann ich
in BlueJ, hier mal ein Quadrat erzeugen, zack.
Und dann kann ich hier jetzt sagen, Zeichner,
Zeichne doch mal was. Und zwar mit irgendeiner Farbe,
gelb und mit diesem Quadratjahr. Dann übergebe ich,
ups, das ist jetzt nicht richtig gewesen,
ich möchte hier gelb übergeben und in diesem Feld möchte ich gerne das Quadrat übergeben.
Das heißt, was ich jetzt hier tue, ist,
ich übergebe, aha, das Ding hier unten.
Wir haben bisher uns immer gemerkt, da unten liegen die Objekte.
Jetzt ist die Objektleiste, so haben wir das immer genannt.
Aber eigentlich sind das hier unten Referenzen. Das heißt,
irgendwo haben wir jetzt hier, wenn ich jetzt hier mal draufklicke,
dann sieht man hier, da ist irgendwo, das ist unser Objekt.
Das ist so unsere Visualisierung in BlueJ von einem Objekt.
Das hier ist nur eine Referenz darauf
So, und diese Referenz übergebe ich jetzt, die kopiere ich jetzt hier rein.
Und dann kann diese Methode tatsächlich mit dieser Referenz auch was machen.
So, also das wird ganz normal weiterverarbeitet. Das heißt,
diese Methode hat jetzt in ihrer Ausführung Zugriff unter anderem auf
dieses komische Ding hier gehabt. Ihr seht hier auch zum Beispiel,
das ist jetzt hier geändert worden auf gelb.
Die Farbe ist auf gelb geändert worden, weil ich ja
auch mit als Parante übergeben habe, macht die Wand gelb.
Okay. Bei der Zuweisung einer Referenzweihung wird die Referenz kopiert,
nicht das referenzierte Objekt. Auch das ist vielleicht nochmal ganz
interessant, das hier live zu sehen in Blue Jay.
Ich habe ja nochmal diese, dann lassen wir das mal offen.
Ich habe Hier jetzt diese Variable, diese Referenz, Quadrat 1.
Das ist aber, die hat auch einen Namen,
also es ist auch mehr oder weniger eine Referenzvariable.
Ich kann jetzt mal sagen, ich deklariere eine weitere Variable, Quadrat
Q. Machen wir Q. Qua. Und die soll gleich
sein Quadrat 1. Das kann ich so schreiben,
weil Quadrat 1 ist eine Referenz und ich kann diese Referenz
einem weiteren Quadratvariablen zuweisen
So, jetzt habe ich hier also mein Qual und das ist eine Objektreferenz.
Auch wieder eine Referenz. Er sagt ja auch,
hier ist es nur Objektreferenz, er zeigt das sogar an.
Vom Typ Quadrati ziehe ich hier mal rüber.
Da habe ich jetzt hier zwei Referenzen. Es sind aber
nicht zwei Objekte, sondern es sind zwei Referenzen auf dasselbe Objekt.
Wenn ich jetzt hier Doppelklick mache, wird das nach vorne geholt.
Wenn ich jetzt hier einen Doppelklick mache,
wird das gleiche Objekt nach vorne geholt.
Es sind zwei Referenzen auf dasselbe Objekt.
Ich habe also nur die Referenz kopiert. Und auch wenn
ich etwas per Parameter übergebe, dann übergebe ich nur diese
Referenz als Kopie
Ich kann die munter durch die Gegend kopieren. Das geht
ganz ohne Probleme. Die Dinger sind sehr speziell in Java
und nur mit den Referenzen kann ich was mit einem Objekt machen.
Aber ich kann die beliebig hin und her kopieren.
Ganz unproblematisch. Okay. Hier wird also die Referenz nur kopiert.
Der Gleichheitstest mit dem Operator gleich gleich, prüft die Gleichheit der Referenzen.
Nicht ob, also zeigen sie oft dasselbe Objekt.
Es werden nicht die Objekte miteinander verglichen. Wenn ich
Objekte miteinander vergleichen will, gibt es eine andere Operation,
die werden wir uns im Laufe des Semesters noch näher ansehen.
Die Operation Equals. Da kann ich wirklich Objekte vergleichen.
Aber hier werden nur die Referenzen verglichen
Also, wenn ich zwei Referenzvariable mit gleich, gleich vergleiche,
wird nur geprüft, zeigen sie auf dasselbe Objekt.
Referenzvariable kann den besonderen Wert null haben,
habt ihr jetzt schon gesehen, zeigt dann auf kein Objekt.
Und wenn ihr Exemplarvariablen von Referenz, also Exemplarvariam,
vom Typ einer Referenzvariam hat, dann werden die automatisch auf null initialisiert.
Ja, Zugriff erfolgt über die Punktnotation,
die habt ihr ja nun auch schon gesehen und gehört.
Und hier haben wir es ja auch schon ein paar Mal live gesehen,
auch in diesem Zeichnerprojekt ist das ja mit drin.
Ganz wichtig, ganz anders als in CPlus Plus
kann man mit diesen Referenzen auch sonst nichts machen.
In C Plus kann man Zeiger-Arrithmetik machen, man kann also irgendwie Dinge verändern.
Hier in Java ist es so, diese Referenzen könnt ihr nicht manipulieren.
Die könnt ihr nur kopieren, weitergeben, sonst nichts.
So, jetzt haben wir eben schon gesagt,
wie kommt man denn an so eine? Da war eben
so was, wie kann man denn nicht irgendwie sagen,
ich möchte alle Objekte haben oder so. Es ist ganz einfach,
wenn ihr in einer Methode an ein Objekt rankommen wollt,
dann gibt es, hier sind drei Möglichkeiten beschrieben,
es gibt eigentlich noch eine vierte,
aber die lassen wir mal außen vor.
Warum ist das so wichtig? Warum frage ich hier nach
innerhalb einer Methode
Warum ist das so wichtig innerhalb einer Methode?
Sag mir mal, was ist denn so in Methoden?
Was passiert denn in Methoden? Alles. Alles,
was irgendwie passiert in einem Driver-System, passiert in Methoden.
Vielleicht abgesehen von den Sachen, die in Konstruktoren passieren, in den Initialisierungen.
Aber ansonsten sind Methoden die aktiven Einheiten in einem Java-System.
Da werden Anweisungen ausgeführt. Nur da könnt ihr überhaupt
irgendwas machen in einer Methode. Also seid ihr jetzt innerhalb
einer Methode, wie kommt ihr an eine gültige Referenz?
Also erstens haben wir das ja auch schon gesehen in
dem Zeichnerbeispiel hier
Hier haben wir die Dinger selbst erzeugt. Also zum Beispiel
hier, neues Quadrat, selbst erzeugen. Erste Möglichkeit.
Zweite Möglichkeit, es wird die Referenz als Parameter übergeben.
Habe ich eben hier schon live programmiert. Also ich habe einfach
einen formalen Parameter definiert und dann kann man von draußen so eine Referenz reinreichen.
So kommt dann der Rumpf der Methode auch an eine Referenz. Oder,
und das sehen wir hoffentlich gleich nochmal, man kann auch sehen,
dass ein Klientobjekt eine Referenz in einem Feldobjekt abgelegt hat,
in einer Feldvariabel, in einem in einer Exemplarvariablen.
Und dann ist es tatsächlich so,
in allen Methoden der Klasse kann ich auf diese Exemplarvariablen zugreifen.
Beim Konto war euch das total klar. Ich kann also
in der einen irgendwie einzahlen, in der anderen auszahlen.
In beiden kann ich auch auf diese Saldo-Variable zugreifen.
Genauso ist es mit Referenzvariablen. Die kann ich natürlich auch
da stehen haben. Und dann kann jede Methode eines Objektes
auf diese Referenzen zugreifen. Was dann entsteht, ist das,
was hier angedeutet ist, das allgemeine Objektmodell von Java,
das nämlich tatsächlich wir so Objektgeflechte bauen.
Das heißt also so ein Objekt, wenn ich mir das angucke,
das sind wieder, es ist so diese Andeutung wieder,
es sind lauter Methoden, die kapseln den Zustand.
Das sind hier die Zustandsfelder. Da können primitive Werte drinstehen,
also 1, 2, 3 oder True oder sonst irgendwas.
Das sind diese primitiven Beispiele. Oder es können genau diese komischen Dinger
da drin stehen, die ich jetzt hier eingeführt habe, nämlich die Referenzen.
Und dann zeigt diese Referenz möglicherweise auf ein anderes Objekt,
der hat auch wieder eine Referenz, diese Referenz zeigt es vielleicht null,
weil das soll hier so deuten, das andeuten, das ist null.
Und man kann auch sowas haben, wie bei diesem Zeichnerbeispiel,
dass es Referenzen gibt, die nur innerhalb einer Methode,
die werden da erzeugt, also es wird ein Objekt erzeugt,
es gibt eine Referenz zurück,
benutzt und wenn die Methode zu Ende ist,
ist auch das Objekt weggeschmissen.
Das heißt also, das kann auch durchaus sein,
dass so eine Referenz nur temporär existiert.
Ja, dann entstehen genau solche Objektgeflechte. Ja,
was dann da automatisch passiert ist, dass man die,
weil ich habe ja gesagt, diese Referenzen kann man beliebig kopieren.
Jetzt kann ich so eine Kopie einer Referenz,
ein anderes Objekt weitergeben und auch ein weiteres Objekt.
Das heißt also, mehrere Objekte können dasselbe Objekte referenzieren.
Und das führt zu einer alias Situation, das heißt,
das eine Objekt kann ja Operationen aufrufen unabhängig,
hat ja eine Referenz,
hat ja sozusagen
den Zugang
Na gut, und dann das andere Objekt hat auch eine Referenz
darauf und kriegt aber gar nicht mit, dass der hier irgendwas macht.
Und dann ändert sich für den irgendwie der Zustand von dem Dienstleister,
obwohl er gar nichts gemacht hat.
Das ist etwas, was unangenehm werden kann, aber nicht muss.
Aber es ist natürlich erst mal als Situation da.
Verschiedene Objekte haben Referenzen und das eine ändert und das andere
kriegt das sozusagen nur unterschwellig mit.
Dieses alias Problem in Anführungsstrichen kann man, wie gesagt,
diskutieren, ob es ein Problem ist.
Weil ihr könnt natürlich mit solchen Referenzen beliebig komplizierte Strukturen bauen.
Wenn ihr euch größere Java-Systeme anguckt, das ist herrlich,
zu sehen, was man sich alles so antun kann,
wenn man da nur genügend viele Referenzen hin und her schiebt.
Das heißt, Wartbarkeit und auch formale Betrachtungen zur Korrektheit
werden sehr viel schwerer durch Referenzen.
Deswegen gab es eine Zeit lang eine Bestrebung in der Informatik, sowas rauszuschmeißen.
Referenzen wollen wir nicht, das ist zu kompliziert.
Hat sich nicht so richtig durchgesetzt. Der Witz ist nämlich,
natürlich ist das mächtig und man kann sich mächtig ins Knie schießen,
aber man kann eben halt auch sehr, sehr fähige Strukturen damit bauen.
Und wenn man weiß, wie Referenzen funktionieren und damit umgehen kann.
Wir sind ja kompetente Software-Techniker hier oder wir wollen es werden.
Dann kann man da eben halt sehr,
sehr viel mit richtig machen und gut machen.
Aber wie man da dann auch darauf achtet, in größeren Systemen,
dass das strukturiert bleibt, das ist auch ein fortgeschrittenes Thema.
Wenn wir in SE1 kaum noch weiter betrachten, das ist eine Frage.
Spiegelt ihr die FFR-Zimmer, heißt wie die grüne Zeit,
auch bei dem Quadrat, im Quallat 2, gleiche Rekord 1 ist.
Das meiste können wir dann eben in Klammer 2 auch so verändern,
dass das dann auch noch Verrat 1 wiederzustimmen ist.
Oder ist das dann wohl in Klammer 2? Ja,
das ist eine gute Frage. Ja, ich wiederhole die Frage,
ich wiederhole die Frage. Die Frage war,
wenn ich zwei Referenzen habe, Und an dem einen Objekt,
über die eine Referenz das Objekt verändere,
ob das dann in dem anderen Objekt auch sichtbar ist,
über die andere Referenz auch sichtbar ist.
Und die Antwort ist ja, das ist tatsächlich so.
Ich muss mal gucken, ob ich hier dieses,
ja, ich habe leider kein Konto hier. Ja,
das Blöde ist, dass die Quadrat die ganzen Figurenklassen,
also Kreis, Quadrat, die haben keine sondierenden Operationen.
Ich kann also nicht fragen, ob sich was geändert hat.
Aber man kann es natürlich sehen. Ja, das kann
man natürlich sehen. Das stimmt, das haben wir ja
hier. Das Beispiel, Moment, Moment, Moment
Hier, ich hatte das ja hier schon irgendwo hingelegt, da.
Hier habe ich jetzt zwei Referenzen und da ist das Objekt,
das ist nicht das Richtige, sondern hier ist das eine und hier ist das andere.
Und wenn ich jetzt hier sage, zum Beispiel nach oben bewegen,
dann, das könnte man jetzt nicht gut sehen,
also hier müsste sich ja die X und Y-Position verändern,
ja, nochmal nach rechts bewegen, da müsste sich ja die X-Position ändern,
ja, seht ihr, dann ist aus der 60 eine 80 geworden.
Das kann ich genauso über dieses Ding hier machen,
nach rechts bewegen, wird aus der 80 eine Hunde,
ich kann also über beide das Objekt verändern
Und wenn die jetzt noch, wenn diese Klassen jetzt sondierende Operationen hätten,
dann kann der eine das verändern und der andere könnte
das sondieren und würde diese Änderung auch dann mitbekommen.
Gute Frage. Okay, sonst noch Fragen jetzt zu Referenzen.
Das ist, wie gesagt, es ist nicht ganz einfach.
Und ihr werdet in den Übungen da ausführlich mit in Kontakt kommen.
Wir werden das sehr, sehr intensiv nachfragen. Und wir
werden auch sehr, sehr anspruchsvolle Strukturen bauen mit solchen Referenzen.
In den nächsten Wochen. Das heißt, merkt euch,
das ist ganz wichtig, dann können wir gleich Pause machen.
Es gibt in Java zwei Typ Familien.
Einmal die primitiven Typen in Float Double
Bulien, festgelegte Menge von Werttypen und die haben auch alle eine festgelegte Wertemenge.
Dann gibt es Referenztypen und Referenztypen sind alle anderen. Alles,
was ihr in Java sonst so seht und unter die Nase kommt,
auch string zum Beispiel, sind alles Referenztypen.
Menge der Werttypen fest definiert, Referenztypen,
man kann beliebig neue Referenztypen definieren. Jede Klasse,
die ihr schreibt, ist implizit auch ein neuer Typ.
Und ihr könnt einfach Variablen von diesem Typen deklarieren.
Man kann dann über diese Referenzen Objektgeschlechte bauen, das kann
sehr schwierig werden. Die sind recht unterschiedlich realisiert,
solche schlechte über solche Referenzen in verschiedenen Sprachen kann das auch sehr, sehr unterschiedlich ausfallen.
Java ist in der Hinsicht eine sehr sichere Sprache.
Also erstens kann man diese Referenzen nicht manipulieren, nicht verändern.
Man kann sich auch nicht selbst irgendwie eine Referenz bauen.
Ich kann nicht einfach sagen, ich mache jetzt mal aus
dem Int, mache ich jetzt mal eine Referenz.
Und damit zeige ich irgendwo in den Speicher und kann dann da was ändern.
Im CPlus geht das. Und es ist auch eine sehr
einfache Sprache, dass tatsächlich alle Parameter per Wert übergeben werden.
Auch die Referenzen auf Objekte. Wir haben schon,
vor zwei Wochen habe ich was dazu gesagt,
das ist so Parameterübergabemechanismen gibt. Per Referenz und per Wert
. Und in Java gibt es nur die Übergabe per Wert.
Das heißt, es wird immer kopiert. Also auch diese
Referenzen hier, die werden immer einfach reinkopiert in die Dienstleister-Methode.
Okay, wenn keine Fragen sind, dann können wir jetzt
mal eben fünf Minuten Pause machen. Ja,
nachdem wir jetzt hier gerade uns sehr technisch damit beschäftigt haben,
dass in Programmiersprachen Referenzen eine große Rolle spielen.
In Java spielen sie nicht mal eine große Rolle, sondern eigentlich die zentrale Rolle.
Alles, was ihr machen könnt in Java, geht über Referenzen.
Wenn ihr nicht mit Referenzen umgehen könnt, könnt ihr nicht in Java programmieren.
Ganz banal gesagt. Von daher ist es wirklich gut,
sich da intensiv mit zu beschäftigen. Ein verwandtes Thema,
das wirkt jetzt auf den ersten Blick wahrscheinlich nicht so,
aber wir werden gleich sehen, dass da eben halt Ähnlichkeiten bestehen.
Ein verwandtes Thema ist jetzt der zweite Teil,
nämlich wir werden ein bisschen hier eine Einführung geben in die UML.
Erstmal, was ist die UML überhaupt?
Und dann werden wir uns zwei Diagrammtypen ansehen,
die eben halt für uns dass sie eins zentral sind und wichtig sind.
Erstmal vielleicht noch mal so ein bisschen den Bogen etwas weiter geschlagen.
Es gibt verschiedene Arten von objektorientierten Aktivitäten. Das,
was wir mit euch hier machen in SE1, fokussiert auf objektorientierte Programmierung.
Ja, das ist also das hier unten.
Das ist letztendlich die Frage, wie programmieren wir mit einer objektorientierten Sprache?
Also zum Beispiel mit Java. Programmiersprachen,
objektorientierter Art gibt es schon seit sehr langer Zeit,
also 1967 war so, dass die erste Sprache,
die da auf den Markt kam, Simular,
Und das hat eine ganze Menge mit Mechanik zu tun.
Also es gibt so Regeln wie Dinge miteinander gesteckt,
ineinander gesteckt werden, wie das dann losrattert,
wenn man es ausführt und so weiter.
Wenn man dann ein bisschen größere Programme bekommt,
dann kommt man relativ schnell an die Fragestellung,
wie baue ich denn meine Objekte und diese Software so,
dass sie auch handhabbar bleibt?
Also wie strukturiere, wie entwerfe ich solche Systeme?
Objekte und diese Modellierung ist etwas, was eher sich damit beschäftigt.
Ich habe irgendein Problem in der realen Welt.
Dieses Problem möchte ich irgendwie beschreiben,
ich mache mir ein Modell von diesem Problem und versuche
dieses Modell dann in meine Software
zu übertragen
Und das kann ich objektorientiert machen. Also gibt es auch
objektorientierte Modellierungsansätze? Das ist üblicherweise sehr stark mit einem Anwendungsbereich verbunden.
Also wie bilde ich zum Beispiel Konten geeignet ab in mein
Objekt unter das System? Um sowas geeignet abbilden zu können,
ist es natürlich außerdem nützlich, erstmal zu analysieren,
was ist denn in dem Problembereich überhaupt zentral?
Was sind die zentralen Begriffe? Was sind die zentralen Schwierigkeiten
? Wie kann ich das irgendwie erfassen? Das passiert üblicherweise
in Form einer Analyse und diese Analyse kann man auch
objektorientiert durchführen
Das hat also sehr viel auch damit zu tun,
bei interaktiven Systemen, insbesondere, dass man mit den Menschen redet,
die diese Software irgendwie schon einsetzen und wie sie ihre Probleme
bisher gelöst haben und wie man vielleicht mit einer anderen Software die Probleme besser lösen könnte.
Dann gibt es einen ganzen Strauß an objektorientierten Vorgehensmodellen,
also Ideen, wie man denn objektorientiert auch in Projekten vorgeht.
Und dann gibt es noch sowas wie Meta-Modelle,
also auch die UML hat ein Meta-Modell, nämlich wie,
welche Grundbausteine habe ich überhaupt,
um solche Elemente definieren zu können und beschreiben zu können
Das sind so die Jahreszahlen immer so,
wann so die ersten Veröffentlichungen zu dem Thema irgendwie gekommen sind.
So, und es ist tatsächlich so,
dass es lange Zeit sehr viele verschiedene Objekten und Titelansätze gab.
Die Objektorientierung ist sozusagen nicht auf einem theoretischen Fundament gewachsen,
wie zum Beispiel die funktionale Programmierung, einfach mathematische Funktionen, als Basisabstraktion.
Nein, durch pragmatische Softwareentwicklung und da gab es ganz verschiedene
Schulen, ganz verschiedene Protagonisten der Objektorientierung.
Und die haben dann auch in der Zeit dann gemerkt,
es ist nützlich, wenn wir wenn wir ein System bauen,
auch Zeichnungen machen können.
Also irgendwie Skizzen, wie bestimmte Klassen miteinander zusammenhängen,
wie bestimmte Abläufe funktionieren sollen zwischen diesen Objekten und ähnliches.
Und das gab dann eben halt so eine Notation von Herrn Rombo.
Dann gab es eine Notation von Grady Booot, die Boots Method.
Und das waren so zwei Methoden, es gab insgesamt drei
große Methoden von drei Protagonisten. Und die waren sehr unterschiedlich.
Die einen haben so eine Klasse mit so einem Rechteck gemalt,
die anderen haben so ein abgerundetes Ding gemalt, dann wurden irgendwo Wolken gemalt
Wir hatten in der einen Notation, die bedeutet in der
anderen Notation eine andere Bedeutung, war sehr uneinheitlich.
Und das war so ein bisschen wieder beim Turmbau zur Babel, ganz viele Sprachen.
Man versteht sich nicht, man kann nicht wirklich irgendwie das austauschen.
Und dann haben die drei Leute gesagt,
das werden auch die drei Amigos genannt,
wir setzen uns mal zusammen und versuchen, das zusammenzuführen.
Also zu unifizieren, zusammenzuführen, Unified, Modeling Langled.
Also es ist eine Sprache,
das ist bei der Modeling Language auch ganz wichtig,
es ist eine grafische Sprache, ist also eine Sprache,
um Dinge grafisch zu beschreiben.
Objektnotierte Systeme. Und sie haben sie eben halt auf
eine Notation geeinigt, die dann für alle gelten sollte.
Die ist jetzt schon eine Weile her,
dass das passiert ist. In den 90er Jahren ist
das passiert
Inzwischen gibt es auch schon wieder Überarbeitung und es gibt eine
ganze Menge von Notationselementen in der UML.
Und das Schöne ist eben halt, dass heutzutage die UML wirklich ein Standard ist.
Also das ist die Standardnotation für objektorientierte Systeme. Das heißt,
es ist extrem nützlich, die UML zu lernen und auch zu beherrschen.
Da gibt es, wie gesagt, dicke Dokumente.
Hier ist mal so eine klassische Marketingfolie.
Wofür ist die UML denn da? Naja, das ist
ganz schön. Die haben halt gesagt, das hat diese
vier Ansprüche
Hier ist es einfach übersetzt. Die UML ist eine Sprache,
um die Elemente eines softwareintensiven Systems zu visualisieren,
zu spezifizieren, zu konstruieren und zu dokumentieren.
Und da geht es jetzt los, jetzt kommt ihr mal in
den Genuss einer persönlichen Einschätzung gegenüber, wir vermitteln Schulwissen.
Das ist sozusagen die Selbstbeschreibung der UML.
Dafür sind wir da für diese vier Dinge.
Und wir jetzt hier an der Uni Hamburg mit der Software-Technikgruppe.
Wir sagen halt, wir sind da ein bisschen skeptisch
bei einigen dieser Punkte
Sofort mit im Boot, wenn es darum geht,
Systeme zu visualisieren. Dafür ist es super. Also,
dass ich ein Objektsystem, ein Klassendiagramm zeichne,
um zu zeigen, welche Klassen sind denn überhaupt beteiligt?
Super. Dafür ist es sehr, sehr gut geeignet.
Wenn ihr tatsächlich euch mal das hier anguckt,
dann ist das hier ein UML-Diagramm,
abgesehen vielleicht von diesem komischen Zeichnungs-, von diesem kleinen Zettel hier.
Aber das ist ein UML-Diagramm, das formal sich wirklich an
die Notation der UML hält.
Und das ist ein Klassendiagramm
Das heißt, wir sehen hier verschiedene Klassen.
Und wir sehen irgendwie Pfeile, die sagen, naja,
Zeichner benutzt Kreis, Zeichner benutzt Quadrat, Zeichner benutzt Dreieck.
Und die wiederum benutzen die Klasse Leinwand. Das ist also eine Benutztbeziehung,
die hier in dieser grafischen Notation mit dargestellt werden kann.
Also zum Visualisieren super geeignet. Dann sind wir uns auch sofort einig,
dass man damit auch objektnetische Systeme sehr schön dokumentieren kann,
dass man einfach sagen kann, naja,
da ist ein System und ich sehe jetzt mal das Klassendiagramm und kann dadurch irgendwie sehen,
wie Dinge zusammenhängen.
Also das ist sehr eng zusammen, visualisieren und dokumentieren.
Jetzt gibt es aber dann auch Leute, die sagen,
naja,
man kann damit auch spezifizieren
Da gibt es dann wirklich Leute, die sagen,
na, wir malen solche Diagramme, ja,
und reichern das dann an mit so Informationen, wie die Methoden heißen,
also in so einem UML-Diagramm kann noch mehr drinstehen,
als nur der Klassenname, ja,
in so einem Klassendiagramm.
Hier steht ja nur der Klassenname drin. Wir kommen gleich dazu,
da kommt noch mehr. Und wenn man dann diese Informationen
in dieser schönen UML-Notation da alle reingemalt hat und reingeschrieben hat,
dann kann man auf den Knopf drücken und dann wird ein Programm generiert.
So. Zumindest ein Programmgerüst, wo man dann in den Methoden
vielleicht noch die Anweisungen reinschreiben muss. Nette Idee,
modellgetriebene Modeldriven Architecture, ein Schlagwort, Project Management Group.
Ist nicht wirklich abgehoben, würde ich mal sagen.
Also das war ein bisschen viel versprochen. Genauso wie es
Leute gibt, die wollen die UML als Programmiersprache einsetzen.
Also hier richtig Software konstruieren mit der UML. Ich schreibe sozusagen
in UML ein Programm. Völlig am Sinn der UML vorbei.
Die UML ist eine Modellierungssprache. Damit möchte ich modellieren.
Ich möchte weich Dinge beschreiben können, auch unscharf.
Und das echt scharfe Zeug passiert in den Programmiersprachen.
Da muss man wirklich Farbe bekennen, das ist hart,
da wird man genau festlegen, was, welche Anweisung bedeutet.
Die Semantik von Programmiersprachen ist eben halt hoffentlich sehr scharf definiert.
Bei der UML ist das nie der Fall gewesen.
Die UML war immer so ein Hilfsmittel,
um Menschen gemeinsam über Objektsysteme sprechen lassen zu können und immer
halt irgendwelche Zeichnungen macht, die alle einigermaßen verstehen.
Aber es gibt Leute, die wollen irgendwie die UML zu einer Programmiersprache machen.
Hat bis jetzt noch nicht funktioniert. Wird auch meiner Meinung
nach nicht dazu kommen. Aber es gibt eben halt Ansätze
in der Informatik und ich will die jetzt nicht diskreditieren.
Wir haben einfach eine Meinung dazu.
Die Meinung muss nicht
richtig sein
Klar, wir können auch falsch liegen, aber nur,
dass ihr es wisst, es gibt da auch andere Haltungen dazu.
Wir sind sofort dabei, visualisieren und dokumentieren.
Und dann sieht man eben halt hier,
es gibt eine ganze Menge an Diagrammtypen in der UML.
Es gibt also Klassendiagramme, Objektdiagramme, Komponentendiagramme, Paketdiagramme.
Und das sind Diagramme, mit denen man die Struktur eines Systems beschreibt.
Also die statische Zusammensetzung. Und da gibt es aber auch Dinge,
mit denen kann man Verhalten beschreiben, also tatsächlich Abläufe,
visualisieren, Activity, Aktivitätsdiagramme, Use-Case-Diagramme, Sequenzdiagramme,
alles Mögliche.
Das ist eine ganze Menge Zeug
Und wir fokussieren uns hier auf Klassendiagramme und auch Objektdiagramme.
Die sind sehr dicht beieinander. Und ich werde jetzt mal versuchen,
diese Unterschiede zwischen diesen Diagrammen auch ein bisschen aufzuzeigen.
Hier haben wir ein Objektdiagramm. Wohlgemerkt kein Klassendiagramm. Ich
rede jetzt erst mal über Objektdiagramme. Weil das ist ja
das, was wir jetzt schon gesehen haben, Objekte.
Das ist jetzt mal eine diagrammartige Darstellung eines Objektes.
Das ist die formal korrekte Version. Es ist auch so,
die UML ist sehr, sehr entspannt.
Also es gibt sehr viele Möglichkeiten, Dinge wegzulassen oder hinzuschreiben.
Also es ist alles Das ist genau für den Zweck flexibel
zu sein, ist es eben halt nicht sehr hart.
Bei einer Programmiersprache seid ihr ja immer gezwungen,
genau euch an die Syntax zu halten. Ha, genau.
Das ist bei der Modellierung irgendwie ein bisschen anders. So,
es gibt immer bei diesem Objektdiagramm so drei Bereiche,
da sind so durch Striche voneinander getrennt, gibt einen oberen,
einen mittleren, einen unteren Bereich.
Im oberen Bereich steht der Objektbezeichner und ein Klassenname.
Also man sieht hier zum Beispiel,
das ist der Name dieses Objektes und das ist der Typ,
also die Klasse des Objektes.
Und dann gibt es hier die, ja,
wie soll man es nennen,
die Attribute in der UML heißen die Attribute,
das sind mehr oder weniger
unsere Exemplarvariable
Es ist halt, wie gesagt, in der UML kann man
ja mehr machen. Man muss nicht unbedingt Objektuntertitelsysteme damit beschreiben.
Aber die heißen da eben halt Attribute in der UML.
Und dann gibt es hier die Methoden, die sind in dem unteren Bereich.
Das ist einfach so die klassische Aufteilung, Name, Attribute,
Methoden. Und diese Methoden können auch durchaus Parameter haben,
die können auch ein Ergebnistyp haben und so weiter.
So, jetzt kann alles mögliche weggelassen werden. Objektbezeichner,
Klassenname, wenn der Objektbezeichner weggelassen wird,
dann musst du aber so einen Doppelpunkt stehen.
Also ich kann diesen Objektnamen hier weglassen
Felder, habe ich schon gesagt, heißen in der OML Attribute.
Ich bin mit dem Begriff Attribut nicht so glücklich in der objektotheten Programmierung.
In der Modellierung macht das gut passend. Bei der Programmierung
ist das eben halt nicht so ein passender Name.
Und diese Methodennamen können auch alle weggelassen werden.
Deswegen so ein Blue-Jay-Diagramm, so ein Klassendiagramm in Blue-Jay,
ist auch ein formal korrektes OML-Diagramm. So,
ganz wichtig jetzt, das ist auch so ein Klassiker,
in einem Objektdiagramm der UML ist es möglich,
an einem Objekt auch einen Namen zu vergeben.
Nun ist es so, dass Objekte,
mit denen ihr hier umgehen werdet in Java.
Die haben garantiert keine Namen. Es ist einfach so,
diese Objekte sind irgendwo im Speicher und dann gibt es Referenzen
und ihr habt eine Referenzvariable vermutlich, in der die Referenz gespeichert ist.
Und diese Variable, die hat einen Namen.
Aber das Objekt ist etwas Namenloses. Wenn ihr euch
noch an dieses eine Beispiel hier erinnert,
ich mache hier nochmal so ein Quadrat, nenne das mal irgendwie Q1.
Und jetzt sage ich hier irgendwie Quadrat
Q2 ist gleich
So, da habe ich hier Q1. Nee, Q2 wollte ich haben.
So, dann habe ich jetzt hier, zack,
mein Q2. So, jetzt habe ich zwei Referenzen.
Jetzt mache ich hier einen Doppelklick und dann wird mir dir
das Objekt angezeigt. Da steht jetzt aber Q2.
Warum steht da Q2? Wenn ich jetzt hier draufklicke,
dann ist das doch auch Q1. Ich habe hier zwei Referenzen.
Die eine, High Score 1, die andere heißt Q2,
aber an dem Objekt steht Q2 dran.
Warum soll es der eine Name der Richtige sein
Das ist einfach Quatsch, das Objekt selbst zu benennen.
Das ist leider eine Schwäche von Blue Jay,
dass die hier oben glauben, irgendeinen Namen hinschreiben zu müssen.
In Java ist es einfach falsch. Aber ein Objekt hat
keinen Namen, sondern die Referenzen bzw. die Referenz variablen,
mit denen ich darauf zugreife, die haben Namen.
Das werden wir gleich noch mal ein bisschen an einem anderen Beispiel sehen.
Okay, wir machen das pragmatisch ein bisschen anders.
Wir sagen erstmal Objektdiagramme, um sie zu unterscheiden von Klassendiagrammen
oder besser unterscheiden zu können, haben so abgerundete Ecken.
Also Objekte sind sowas Rundes. Das ist ja hier auch,
wie gesagt, im Blue Jay auch ganz hübsch,
die haben das auch so gemacht,
Objekte sind ja so ein bisschen rund.
Und da unten sind sie ja auf der Objektleiste,
sind sie auch so ein bisschen abgerundet.
Also machen wir auch unsere Objektdiagramme hier so abgerundet.
Dann machen wir es immer so, wenn wir hier
in Java irgendwelche Objektligame zeichnen, es gibt keinen Namen.
Da kommen keine Namen rein, also stellt immer nur Doppelpunkt.
Und dann der Typ, also die Klasse. Das Ganze
muss unterstrichen sein. In Objektdiagrammen ist es halt unterstrichen.
Das ist wieder so ein bisschen, ist so gemacht.
Dann sagen wir, die Dinger heißen Felder,
die hier in den Objekten drinstehen.
In der Klassendefinition stehen Exemplarvariablen. Und die Objekte haben dann
Felder, so tatsächlich Felder. Und dann schreiben wir auch
gerne die Werte dazu
Also das heißt, das ist ja ein Objekt,
das hat ja irgendeinen Zustand. Das heißt also,
irgendwie wird hier in den Feldern irgendwas drinstehen und
den kann man ja auch mit angeben.
Okay. Dann die Methodennamen sind halt genauso wie immer.
Also das ist die Art und Weise, wie wir Objektdiagramme
gerne darstellen. So, ganz wichtig ist jetzt,
Untertitel der Amara.org Untertitel der Amara.org
Untertitel der Amara.org
Untertitel der Amara.org Untertitel der Amara.org
Untertitel der Amara.org