Ja, prima. Dann lasst uns anfangen. Herzlich willkommen
zur elften Vorlesungssoftwareentwicklung 2. Heute haben wir noch eine Spezialsituation,
eine Schulklasse aus Mutterstadt ist da.
Könnt ihr mal ganz kurz irgendwie Arm heben, so,
ja, genau. Willkommen, ja. Gymnasio-Mutterstadt,
Gäste, die sich einfach mal den Uni-Betrieb angucken wollen.
Und kurze Erläuterung, das ist hier jetzt eine Vorlesung im
zweiten Semester. Das heißt, die Studierenden haben vorher schon
relativ viel über Programmieren
mit Java gelernt
Im ersten und der zweiten Semester jetzt. Das Ganze läuft
hier in der Vorlesung und aber auch in den Übungen,
die bei uns in Laboren stattfinden,
die habt ihr ja auch schon besucht, soweit ich das mitbekommen habe.
Was ihr auch mitbekommen habt möglicherweise, ist, dass ich hier ein Mikro trage,
dahinten steht eine Kamera, also diese Vorlesung wird auch aufgezeichnet.
Ihr braucht aber keine Angst zu haben, dass irgendwas,
was ihr sagt, mit aufs Mikro,
mit auf die Aufnahme kommt, das ist also relativ entspannt hier,
wenn ihr Fragen stellt, muss ich normalerweise die Frage wiederholen,
damit das dann auch aufs Band mit draufkommt.
Speziell für euch, aber bevor ich das jetzt mache,
bevor ich jetzt, will ich erst mal noch was anderes erzählen.
Das ist etwas, was mir über große Freude macht,
Werbung zu machen für die Betreuung in SE1. Ihr habt jetzt diesen Übungsbetrieb,
fast zwei Semester mitgemacht bei uns, sehr intensiv betreut in den Laboren,
was ihr sicherlich auch mitbekommen habt bei so einer großen Anzahl von Studierenden,
brauchen wir sehr viele ständische Hilfskräfte,
die uns dabei helfen bei der Betreuung.
Und da sind jetzt immer so die finanziellen Fakten drauf,
das ist so möglicherweise auch am Rande interessant,
also wie viel verdient man denn, wenn man bei uns Hilfskraft ist.
Ihr seht, dass es ganz okay, 615 Euro ungefähr,
wenn ihr eine Übungsgruppe pro Woche betreut, wenn ihr zwei macht,
also zwei SWS sind das schon, 1230.
Ihr müsst 14 Labortermine betreuen, dann auch immer bei
der Betreuerbesprechung dabei sein, jeweils eine Stunde.
Also das ist so der Aufwand, den man so rechnen muss.
Viel spannender ist natürlich nicht das Geld, sondern was man dabei alles lernen kann. Und ich glaube,
fast kein SE1 oder SE2-Betreuer würde sagen,
dass das bereut hat, das bei uns mitgemacht zu haben,
weil man einfach die Inhalte nochmal, sagen wir,
von der anderen Seite lernt, Nicht nur einmal sozusagen Durchmus,
sondern dann auch aufgefordert ist, anderen dabei zu helfen,
die Inhalte zu verstehen.
Das trainiert einige Softskills bei uns, weil wir ja diesen Präsenzbetrieb haben.
Also ihr müsst tatsächlich auch Mut entwickeln, auch Leute zuzugehen.
Ihr müsst offen sein. Aber wie gesagt, ihr vertieft
auch das eigene Verständnis. Und was bei uns eigentlich auch
immer möglich ist, ist Kritikloswerden in der Betreuerrunde.
Das dürfen die Studien natürlich auch, aber in der Betreuerrunde
seid ihr sozusagen dichter dran an den Leuten,
die festlegen, was passiert in SE1, in SE2.
Und dann könnt ihr durchaus auch entsprechend konstruktiver Kritik auch das mitgestalten.
Wenn ihr Interesse habt, nur mal so eine kurze Erhebung,
wer es interessiert, das mitzumachen im nächsten Wintersemester,
ja, das ist ja super.
Das sind ja wieder so eine Handvoll, mindestens fast zehn, toll.
Sehr schön, schickt eine E-Mail an Christian. Christian Spee,
der kümmert sich um alles Weitere und dann freuen wir uns,
wenn wir talentierte und motivierte Leute haben bei uns in SE1 und SE2.
Das haben wir die letzten Jahre eigentlich immer ganz gut hingekriegt,
da sozusagen den eigenen Nachwuchs wieder zu zu fördern.
Was vielleicht das noch interessanter macht für diejenigen von euch,
die Interesse daran haben, ist,
das ist inzwischen mehr oder weniger anrechenbar als eine Lehrveranstaltung.
Im ABK-Anteil, also im Allgemeinen berufsqualifizierende Kompetenzenanteil des Studiums,
könnt ihr tatsächlich einen Drei-Leistungspunkte-Modul belegen, wenn ihr bei uns Betreuung macht.
Ihr müsst dann zusätzlich zu dem,
was ihr in den Übungen an Betreuung zu tun habt,
noch ein Wochenend-Workshop eingangs machen am Anfang des Semesters.
Da geht es vor allen Dingen um Soft-Skills für Betreuungstätigkeiten.
Dann gibt es einen weiteren Wochenend-Workshop, so in der Mitte des Semesters.
Wir haben das jetzt gerade in SC2 auch gemacht und dann
gibt es nochmal einen Abschlusstermin. Also man muss nochmal Zusatzzeit investieren,
aber das ist natürlich, sagen wir, eine sehr,
sehr attraktive Möglichkeit, nochmal drei Leistungspunkte zu bekommen mit Tätigkeiten,
die wie gesagt nicht nur für euer Studium relevant sind,
sondern auch später im Berufsleben, wenn ihr anderen Leuten Softwarekonzepte näher bringen wollt.
Soweit so gut, also meldet euch zuhauf bei Christian.
Ich mache das mal eben zu hier,
das brauchen wir auch nicht mehr
Okay, dann auch für die jetzt,
die neu da sind, die Schüler aus Mutterstadt,
was ich in dieser Veranstaltung eingeführt habe,
eigentlich schon im letzten Semester, in der SE1,
aber in der SE2 jetzt auch schon durchgängig benutze,
ist ein Classroom-Response-System.
Und wenn ihr jetzt ein Smartphone zufällig in der Tasche habt,
dann könnt ihr das auf diese URL lenken.
Das ist eine Möglichkeit,
dann könnt ihr an einer Abstimmung oder an einer Umfrage teilnehmen,
die ich jetzt hier gleich durchführen werde.
Es geht auch vielleicht noch einfacher,
wenn ihr ein Smartphone habt,
das ein QR-Code-Scanner hat
Ich starte jetzt hier einfach mal diese Abstimmung.
Denn heute geht es um Fachwerte, also um Werttypen.
Und das ist so ein Bereich in der objektnotierten Programmierung,
den wir so abgegrenzt haben,
der sehr stark verwandt ist mit Konzepten in der funktionalen Programmierung.
Und deswegen werde ich jetzt mal eine Frage stellen zu
eurem Vorwissen, was funktionale Programmierung angeht.
Ja. Und zwar folgendermaßen. Und jetzt kann ich hier erstmal,
bevor ich die Umfrage starte, kann ich nochmal diesen QR-Code zeigen.
Also wenn jetzt irgendjemand von euch einen QR-Code-Scanner auf seinem Smartphone hat,
dann könnt ihr jetzt diesen QR-Code upscannen hier auf der Folie
Und dann könnt ihr tatsächlich direkt, werdet ihr direkt auf die Seite umgeleitet,
auf der ihr dann an dieser Umfrage teilnehmen könnt.
Bei wem das nicht klappt, das geht dann eben halt auch mit der URL,
die hier unten steht, die Tiny Your Royale,
da kommt ihr dann auch mit dem Webbrowser auf diese Seite.
Das ist eine interessante Möglichkeit, direkt Feedback einzuholen in Veranstaltungen.
Das geht so ein bisschen Richtung, falls ihr das kennt,
wer wird Millionär, aber das sollte natürlich hier nicht dazu führen,
dass wir in eine Quizshow uns umwandeln,
aber es ist ganz interessant, wie gesagt,
einmal Vorwissen abzufragen und deswegen hier,
wie viel Vorerfahrung hast du mit funktionaler Programmierung?
Ich starte jetzt mal diese Umfrage und jetzt können alle natürlich
daran teilnehmen
Vorerfahrung mit funktionaler Programmierung, also entweder gar keine oder ein wenig,
ein bisschen im Selbststudium oder hat er das Thema schon in der Schule?
Kann ja auch sein, einige von euch. Da gibt es möglicherweise die Leute,
die schon professionell in mindestens einer funktionalen Sprache programmieren.
Und dann gibt es natürlich auch noch die Leute, die irgendwie,
was weiß ich, umfangreiche Erfahrungen haben mit mehreren funktionalen Sprachen.
Da würde ich jetzt mal nicht darauf wetten,
dass das hier viele sind, aber man weiß ja nie.
Okay, und da unten rechts wird jetzt angezeigt,
wie viele Leute schon ihre Stimme abgegeben haben.
Ja, das ist jetzt wahrscheinlich gemischt,
einmal über diesen Empfänger hier, über diese Clicker.
Also wir haben auch so Clicker wie bei Wer wird Millionär,
die sind da vorne am Eingang,
mit denen kann man auch teilnehmen
Oder wie gesagt, über ein Smartphone oder internetfähiges Gerät.
Genau. So, dann können wir das mal anhalten hier,
56 Stimmen reicht ja auch erstmal, gucken wir mal,
was so dieses Ergebnis ist.
Hier gab es jetzt keine richtige Antwort,
hier geht es hier nur um eine Umfrage.
Ja, also doch überwiegend, keine Vorerfahrung,
einiges schon so ein bisschen. Dann gibt es Leute,
die hatten das schon in der Schule und umfangreiche Erfahrungen mit mehreren Funktionen.
Es gibt also tatsächlich Leute, die das von sich behaupten
, sehr schön. Schön, schön, schön.
Aber es geht nicht um funktionale Programmierung, keine Angst.
Also ich werde über was anderes sehen. So,
jetzt habe ich aber noch ein Problem.
Das wollte ich mal eben kurz besprechen.
Ich habe immer mal Probleme
Aber ich habe jetzt hier ein Programmierproblem.
Und da könnt ihr mir vielleicht helfen.
Das macht nämlich nicht das, was es machen soll.
Wer kann mir sagen, was ich falsch mache?
Ich zeige das Programm mal. Das ist in Blue Jay gebaut.
Das ist eine Entwicklungsumgebung für Programmierungs-, für objektnetierte Programmierung,
für die Lehre von Objekten der Programmierung.
Das ist so eine kleine Anwendung hier, so ein OML-Diagramm.
Das ist eine Anwendung, die nach den Entwurfsregeln hier in
dieser Veranstaltung mehr oder weniger gebaut ist.
Ich starte die erstmal, damit ihr seht,
was ich eigentlich für ein Problem habe
Ja, hier, das ist so ein bisschen aus der Mediathek entlehnt.
Ihr wisst, in der Mediathek konnte man irgendwie Medien verleihen,
an Kunden und Ähnliches. Und das ist jetzt
die Medienerfassung. Das ist also so ein kleines Subwerkzeug,
mit dem man da irgendwie Medien erfassen kann.
Habe ich ja mal so ein bisschen hingehackt. So,
jetzt möchte ich hier so zeigen, kann man jetzt so Sachen erfassen?
Ich kenne jetzt hier irgendwie ein Interpret nehmen, Paul Weller,
das Album, das Paul Weller, sagen wir mal,
56 Minuten Laufzeit.
Und das war irgendwie das erste Soloalbum von ihm.
So. Und kann ich jetzt
hier erfassen
Und dann wird hier und in dieser Liste aufgeführt und jetzt möchte ich noch
ein weiteres Album erfassen von ihm, was weiß ich, Wild.
Wood hat vielleicht 64 Minuten gehabt. So,
und jetzt möchte ich aber hier, und das ist das,
was ich eigentlich zeigen will, ich möchte jetzt,
ich habe mir was ganz Schlaues überlegt.
Ich habe mir überlegt, ich möchte so als Abkürzung hier jetzt auch drei Sterne hinmachen können.
Und das soll dann umgewandelt werden in einen anderen Text,
so was wie prächtig, prächtig. Oder ich habe einen Kollegen,
der ist großer Wagner-Fan und der hat also diese, er Dinge bewertet,
dann hat er so verschiedenes an eine Skala von Bewertungsbegriffen.
Prächtig ist so okay und prächtig prächtig ist schon gut.
Herrlich ist vier Sterne und fünf Sterne wäre dann göttlich,
das ist die höchste Stufe. Gut, man muss dann
natürlich Wagner-Fan sein, um das zu mögen.
Aber auf jeden Fall hätte ich jetzt hier,
wenn jetzt hier drei Sterne eingebe oder ich gebe mal fünf Sterne ein,
dann sollte da jetzt eigentlich als Kommentar und der Kommentar steht ja hier dahinter,
den ich eingegeben habe, sollte der umgewandelt werden in göttlich.
Das funktioniert aber nicht. Irgendwas ist da faul in
meiner Anwendung. Das heißt, diese fünf Sterne werden einfach
so direkt übernommen
Das ist doof und jetzt können wir mal in den Quelltext reingucken.
Wie gesagt, das ist so gebaut,
wie ihr das mehr oder weniger kennt.
Also hier ist das Werkzeug mit der UI. Die UI
brauchen wir uns nicht angucken. Hier ist das Material,
die Compact ist, das ist irgendwie hiermit mietbar und mietbar Info.
Das ist so, das kennt ihr schon so ein bisschen aus der Mediathek.
Und hier haben wir so einen Fachwertdatum, werden uns heute
ja ausführlicher angucken. Aber hier ist jetzt das Startup,
der macht nichts weiter als so ein Werkzeug zu erzeugen.
So, und jetzt gucken wir uns mal hier den Quelltext
von dem Medienerfasser an. Geht ja hier um Programmierung.
Konstruktor erzeugt sich eine UI und dann kommt registriertere Listener,
so wie man uns erwartet, registriere Listener.
Wir haben also einen erfassen Button,
da wird ein Listener rangehängt, der sagt, Medium erfassen.
Und das andere ist hier irgendwie,
man kann auch das letzte Medium löschen in der Liste.
Also ich kann das mal zeigen hier,
ich kann jetzt das Ding da tatsächlich einfach löschen,
dann ist es wieder aus der Liste raus.
Ja, so, toll, toll. Und jetzt haben wir
also Medium erfassen. Das ist das, was mich interessiert
. Es werden also hier aus dem, aus der UI
irgendwelche Felder ausgelesen, Text, getext und so weiter.
Titel, Interpret, Laufzeit. Und dann wird hier versucht aus dem Text,
der da in das Laufzeitfeld eingegeben wurde, wird versucht,
einen Integer zu machen, also in Laufzeit hier,
wird irgendwie Integer,
Pass Int aufgerufen
Wisst, das kann schief gehen. Deswegen ist es hier
ein Trike-Catch-Block. Und dann gibt es hier Catch,
Numberformed Exception. Dann kann man also eine Meldung rausgeben.
Bitte nur ganze Zahlen als Laufzeit eingeben. So,
und ja, dann wird hier einfach tatsächlich,
wenn das geklappt hat mit der Laufzeit, dann wird hier ein Material erzeugt.
Und das sollte dann eigentlich in einen Service eingetragen werden,
habe ich jetzt hier weggelassen. Und dann, so. Ja,
und jetzt ist hier aber eine Sache, Kommentar,
da habe ich ja dieses Ding jetzt reingesetzt, Kommentar umwandeln.
Ich möchte also, dass der Kommentar umgewandelt wird in etwas anderes.
Das habe ich da schon reingebaut. Wo ist jetzt Kommentar
umwandeln? Hier ist Kommentar umwandeln
Jetzt gebe ich also einen String rein, zum Beispiel irgendwas,
was irgendwie fünf Sterne hat oder drei Sterne.
Und wenn es fünf Sterne sind, dann soll als Ergebnis rauskommen, göttlich.
Und wenn ich es drei Sterne soll da als Ergebnis rauskommen,
prächtig, prächtig. Sieht doch wunderbar aus, meinen Quelltext.
Was ist denn das Problem jetzt hier? Ja,
dahinten meldet sich jemand. Aha, oha, oha.
Stimmt. Jetzt, wo du es sagst. Ja,
er sagt, ich würde Strings mit Equiels vergleichen.
Das können wir ausprobieren. Also das wird ja hiermit
gleichgleich gemacht. Aha, also Kommentar, Equiels
Das hier, da muss ich natürlich noch irgendwie hier
so noch eine Klammer zumachen, auf Kommentar equals das.
Und dann machen wir das hier mal auch, was auch wirklich funktioniert.
Equals. Kann man übersetzen, ja, lässt sich übersetzen.
Schön, schön, übersetze das mal. Mach mal
ein Start-up. Oh oh, gucken wir mal,
Interpret, zack, irgendwas reintippen, Laufzeit, 45,
Kommentar, drei Sterne,
CD erfassen
Oh, prächtig, prächtig. Ja, sensationell. Also
da müssen wir nochmal noch weiter probieren hier. Fünf Sterne,
göttlich. Toll. So, vielen Dank für die Hilfe.
Ich gebe zu, ich habe das gewusst, ja.
Keine Frage. Was passiert in dieser Anwendung ist?
In der GUI wird eine Zeichenkette vom Typ String erzeugt.
Also dieses Textfeld liest die Zeichenkette ein und macht einen String daraus.
Im Programm wird ebenfalls ein String erzeugt,
nämlich an dieser Stelle dieses Literal.
Ja,
also dieser Quelltextstelle
Und selbst wenn beide Zeichenketten aus denselben Buchstaben bestehen,
dann sind diese beiden Zeichenkettenobjekte verschiedene Objekte. Und das heißt,
der Referenzvergleich liefert Falts in diesem Fall. Das ist das,
was wir ja auch schon in SE1 ausführlich thematisiert haben.
Also bitte, wenn ihr Strinks vergleicht, in Java,
dann immer nur über Equals. Man sollte Strinks niemals über
gleich gleich vergleichen. Es gibt tatsächlich keinen guten Grund,
warum man das gleich gleich bei Strings verwenden sollte.
Ich habe bisher keinen gefunden. Also die Frage ist tatsächlich,
wie nützlich ist denn die Tatsache,
dass das geht
Wie nützlich ist die Tatsache, dass ich mehrere Zeichenketten,
die aus den gleichen Buchstaben,
also wenn ich mehrere Zeichenketten aus den gleichen Buchstaben erzeugen kann,
also es sind die gleichen Zeichenketten, aber sie werden als verschiedene Objekte angesehen.
Wann ist das nützlich, dass ich das tun kann?
Hat irgendjemanden mal spontan einen Vorschlag, wo man das gebrauchen könnte?
Es ist so üblicherweise der Punkt in der Vorlesung,
wo ich dann den besten Preis ausschreibe,
den ich so habe, nämlich einen Snickers, für diejenigen,
die mir wirklich mal einen nützlichen Hinweis geben dafür.
Da meldet sich jemand? Wahrscheinlich nicht nützlich in dem Sinne,
aber es gibt auf jeden Fall eine Situation im Jahr,
wo man den Leichtrechtsformat des Lebens braucht, genommen hat.
Gnade ist. Oha. Okay, er sagt,
es gibt eine Situation in Java, wo man das braucht.
Nämlich, wenn man wissen will, ob er Nald ist.
Okay, naja. Ja, da ist tatsächlich was dran.
An der Stelle ist es sinnvoll. Die Frage ist,
inwieweit ist es sinnvoll, dass er dann den Referenzvergleich macht
und nicht tatsächlich beim Gleichgleich den Equals-Vergleich automatisch ausführt.
Denn das ist ein Spezialfall, richtig.
Man muss natürlich feststellen können, ob eine String-Variable Nald ist.
Ja, da ist noch eine Meldung. Ich bringe nochmal
ändern will
Soweit mit seinem Anhänger möchten, dass der das Trikot gibt
, verhalten. Und dann dachte ich mir, okay,
bei euch in den Kamerastein kommen, die haben einfach genauso ausgesehen.
Okay, er sagte, wenn er ein Strink verändern will,
also zum Beispiel ein Zeichen anhängen will,
dann möchte man vielleicht vergleichen können,
ob die wirklich verschiedene Objekte sind.
Dazu muss ich natürlich dann den wahrenden Finger erheben und sagen,
dass das Drinks in Java unveränderlich sind.
Also man kann es dringend nicht verändern.
Trinks haben keinen Zustand, da ist noch eine Meldung.
Weil, ich bin auch ein bisschen schwierig,
außer eigentlich,
wenn es
damit erzeugt worden ist
Das ist vielleicht auch ganz schön dazu gekommen.
Das kriegen wir woanders her. Okay, also und unterscheiden,
ob eins dringend aus einer Konstante, aus einem Literal war,
meinst du wahrscheinlich erzeugt wurde, oder irgendwo anders herkommt?
Müsste man drüber reden, in welche Situation man das braucht?
Das ist so, ja. Okay, also meine These
ist, das ist völlig unnütz. Völlig unnütz.
Braucht man nicht. Braucht kein Mensch. Wie gesagt,
nämlich das vom Gegenteil überzeugt, der kriegt einen Snickers.
Da bin ich großzügig. Strings werden in Java speziell behandelt,
aber das eben nicht konsequent. Also wenn man sich das anguckt,
was da in Java passiert ist, dann gibt es fürs
Trinks in der Sprache, in Java explizit divide Literale.
Also wenn das da steht, göttlich, dann ist das vom Typ String.
Das ist dieses Literal, hat den Typ String.
Also ist String schon spezial behandelt in Java.
Dann gibt es den Operator Plus für Strings. Das gibt es
sonst für keinen anderen Typ, außer den primitiven Typen,
dass man mit diesem Plus-Operator was machen kann.
Auch das ist sehr eine sehr klare Spezialbehandlung. Also ad hoc
in Java. Also wenn ich sowas hinschreibe wie prächtig,
plus komm mal prächtig, dann kommt da als Trink raus prächtig, prächtig.
Okay, außerdem sind es dringend Objekte unveränderlich.
Das ist aber eigentlich nichts Besonderes,
weil jeder kann seine Klassen so bauen,
dass die Exemplare unveränderlich sind
Es wäre ziemlich leicht gewesen, in Java reinzubauen. Eine Sonderregel,
die sagt, wenn, zwei Strinks mit gleich, gleich verglichen werden,
dass dann der E-Quids-Vergleich durchgeführt wird und nicht der Referenzvergleich.
Dann wäre das nämlich so, dass Strinks sich genauso verhalten würden,
wie die primitiven Typen in Float und so weiter.
Und genau darum geht es heute, um selbst definierte Typen,
die sich eigentlich so verhalten sollen wie die primitiven Typen.
Ja, stattdessen baden jetzt Generationen von Studierenden immer wieder diesen Fehler aus. Ja,
ich habe jetzt in meinem Programm auch wieder diesen Fehler gemacht,
stundenlang den Fehler gesucht und nicht gefunden und da kommt ein
fixer Student und der klärt mich gleich auch sehr schön.
Gut. Das ist so ein kleiner Auftakt.
Jetzt sind wir hier genau an dem Punkt.
In SE2 haben wir ja diese Entwurfsregeln formuliert für SE2,
immer dran denken, nur für SE2 wirklich relevant.
Darüber hinaus kann man sie eigentlich kaum verwenden.
In der harten Form, wie wir sie hier vorstellen,
aber es ist einfach gut, Regeln zu haben,
um eine gemeinsame Idee von Architektur zu haben.
Und was wir halt sagen, ist,
man sollte so ein interaktives System aufbauen in Werkzeugen,
Services, Materialien, Fachwerten.
Und heute geht es um die Fachwerte.
Die sind hier so in dieser quasi Schichtenhierarchie ganz unten.
Das heißt,
sie sind sehr elementar
Wenn wir in einem bestimmten Anwendungsbereich Dinge modellieren wollen,
wir haben immer gesagt,
wenn man programmiert, dann modellieren wir Dinge,
erkennen Dinge aus dem Anwendungsbereich und versuchen, die abzubilden.
Und es gibt tatsächlich so Dinge, die sind eher wertartig.
Also sowas wie eine Kontonummer oder ein Geldbetrag.
Und die beschreiben wir über Fachwerte. Das ist,
ja, das sind fachlich motivierte Werte.
Ich werde das gleich noch ein bisschen genauer differenzieren.
Und Werte sind tatsächlich ein relativ allgemeines Konzept, das auch Zeichenketten umfasst.
Also ich würde sagen, die Strings in Java sind eigentlich auch Werte.
Und auch natürlich die ganzen Zahlen in Java, die zahlen Typen, beschreiben Werte.
Was hatten wir für Eigenschaften? Wäre das unveränderlich? Wir beschreiben Werte,
programmiertechnisch über Wertetypen und Werttypen sind insbesondere deshalb spannend,
weil sie in eine unveränderliche Wertemenge haben.
Das heißt also, Werte werden nicht erzeugt, wie Objekte,
sondern die sind eigentlich einfach da und man sucht sich den entsprechenden Wert einfach aus der Wettermenge raus,
den man braucht in einem bestimmten Kontext.
Und die Bilder, die Grundkonstanz in einem Anwendungssystem und ich hatte damals gesagt,
wir schauen uns die Wehrtypen in einer der nächsten Vorlesungen an.
Das ist genau heute. Juhu, Fachwerte
Das Ganze ist jetzt so aufgebaut, dass ich zuerst ein
bisschen was sage, warum wir überhaupt über Werte reden.
Warum ist das etwas, was wir glauben,
was relevant ist bei der Modellierung von Objektnotierten Systemen?
Dann, wie erkennen wir denn diese Werte? Und dann ist die nächste Frage,
ja, wenn wir jetzt erstmal, wenn ich einigermaßen gut vermitteln kann,
warum Werte relevant sind, dann ist ja die Frage,
wie gut unterstützen uns Programmiersprachen dabei, diese Werte abzubilden?
Und dann im dritten Teil so,
wie macht das denn konkret Java und was müssen wir tun,
um in Dava unsere Werttypen geeignet zu modellieren?
Ja, Literaturenweise hierzu,
das ist ein klassischer Artikel von dem guten Herrn McLennon,
der hat das schon sehr früh vor über 30 Jahren zum Thema gemacht,
also das Werte und Objekte in Programmiersprachen durchaus verschiedene Konzepte sind.
Und da haben wir auch sehr stark darauf aufgeobert in unseren eigenen Forschungsaktivitäten
in den letzten Jahren, haben auch ein bisschen drüber veröffentlicht.
Und ein anderes gutes Buch, also ein Buch,
was hier auch sehr empfehlenswert ist,
was ich wahrscheinlich auch schon mehrfach empfohlen habe,
ist der Bloch,
den wirklich jeder,
der professionell Java entwickeln will,
kennen sollte
Da wird auch ein bisschen was zitiert werden,
gleich werde ich noch darauf eingehen.
So, ich habe eben schon gesagt, Programmieren ist modellieren.
Also wenn wir programmieren, dann ein erfahrener Programmierer modelliert etwas,
den Anwendungsbereich und bildet das direkt ab in seinem Code.
Also Programmieren ist eigentlich schwer zu trennen von modellieren.
Ich bin ja immer derjenige, der sagt,
man sollte programmieren lernen, schon trennen von modellieren lernen.
Also ein NSE1 machen wir nur programmieren und SE2 jetzt
schon so ein bisschen auch modellieren.
Aber später, wenn man dann eine relativ geübter Programmierer ist,
dann geht das eigentlich sehr stark ineinander über
Diese Idee des Warm-Ansatzes hat Heinz ja auch schon vorgestellt.
Also Menschen arbeiten mit Werkzeugen an Materialien.
Hier ist etwas, was ihr kaum erkennen könnt wahrscheinlich.
Das ist so eine grafische Oberfläche von einem Werkzeug,
das beim Bundesamt für Zivildienst entwickelt wurde, von der Firma von Heinz.
Und wenn man da ein bisschen genauer hingeguckt hat,
dann sieht man hier, da gibt es so Dinge wie
ein Quartal oder ein Antragsdatum oder ein Zeitraum, so Zivildienstleister.
ZDP ist, glaube ich, die Zivildienstleistenden Personalnummer oder sonst irgendwas.
Und das sind fachlich motivierte Werte. Man würde jetzt nicht
sagen, dass das Objekte sind.
Und das ist eben halt eine der Thesen des Werkzeugmaterialansatzes,
aber das ist eben halt deutlich relevant über den Werkzeugmaterialansatz hinaus,
dass man eigentlich sagen kann,
in jedem Anwendungsbereich findet man fast immer fachlich motivierte Werte.
Also ich würde sagen,
ich stelle mich jetzt mal auf die gewagte Seite und sage,
in jedem Anwendungsbereich wird man immer mal sowas finden.
Also zumindest fällt es schwer,
so einige der folgenden Phänomene als Objekte zu modellieren,
also sowas,
einen Zeitpunkt,
Zeitpunkte,
wenn ihr mal darüber nachdenkt
Wisst ihr immer, die muss man erzeugen mit New in Java.
Aber einen Zeitpunkt würde man ja nicht erzeugen.
Also vielleicht erzeugt ja ein Objekt, das einen Zeitpunkt repräsentiert,
aber erst mal so vom Konzept her ist ein Zeitpunkt nichts, was man erzeugt.
Die Zeitpunkte sind einfach da. Das ist eine Zeitachse und
jeder Zeitpunkt auf dieser Achse ist irgendwie auswählbar.
Ich kann sagen, das ist der Zeitpunkt oder der Zeitpunkt.
Die sind einfach da, die werden nicht erzeugt.
Oder auch wenn wir den Zeitraum unserer Klausur ändern,
von 10 bis 12 statt 9 bis 11 oder so,
dann ist es nicht so,
dass wir den Zeitraum ändern,
sondern wir wählen einen anderen Zeitraum und ordnen den unserer
Klausur zu
Gut, 100 Euro sind quasi in doppelter Hinsicht ein Wert.
Wenn sich mal ein Bankkunden die Kontonummer ändert, auch da wieder,
dann ändert sich nur die Zuordnung zwischen Kunde und Nummer.
Nicht die Nummer selbst. Ich nehme eine andere Nummer
und sage, die gehört zu dem Kunden.
Und genauso auch so Sozialversicherungsnummern. Ich weiß nicht,
ob ich das System kennt, wie Sozialversicherungsnummern aufgebaut sind.
Da gibt es richtig so ein Konzept mit Prüfsummen
und da ist dann der erste Buchstabe des Nachnamens drin,
das Geburtsjahr und so ein bisschen rein kodiert.
Und es gibt einfach eine klare Definition, was,
wann eine Sozialversicherungsnummer eine gültige Sozialversicherungsnummer ist.
Im Sinne von syntaktisch gültig
Prüfsummen und allem drum und dran. Aber eine gültige,
also sind taktisch gültige Sozialverbindungsnummer, heißt noch lange nicht,
dass es tatsächlich auch diese Nummer an eine Person vergeben wurde.
Also man muss immer auch noch wieder zuordnen,
da ist ein neuer Mitbürger auf die Welt bekommen und der kriegt jetzt diese Sozialversicherungsnummer.
Gut, das erstmal so als allererste Motivation. Wo kennen wir
noch Werte? Naja klar, also ganz viel mathematische Werte,
haben wir ja schon in der Programmierung kennengelernt.
Die ganzen Zahlen haben wir kennengelernt, die rationalen Zahlen,
also Int und Float beziehungsweise die Verwandten von denen in Java,
Busche Wahrheitswette sind letztendlich auch ein mathematisches Konzept
Kann man jetzt fragen, wenn wir jetzt in einer Objektorientierten Sprache sind,
wie in Java, sind das denn alles Objekte?
Warum sind das, warum sind das keine Objekte?
Also naja, also es ist irgendwie schon komisch zu sagen,
wann haben wir denn schon mal eine 4 erzeugt?
Also die 4 ist nicht erzeugt, die ist einfach da.
Und wir würden auch nie zu der 4 sagen, 4,
ich schicke dir die Nachricht, sei die 5. Kommt selten vor.
So, das ist irgendwie nicht so der Fall.
Und wurde die Zahl P entdeckt oder wurde die erzeugt?
Die wurde auch nicht irgendwie konstruiert, sondern die ist entdeckt worden.
True for falls erzeugt, ist das wichtig, die Reihenfolge?
Nee, ist natürlich nicht wichtig, weil die Dinger werden halt nicht erzeugt.
Das heißt, diese primitiven Typen, die wir aus Java kennen,
da scheinen die Elemente dieser Typen durchaus eher Werte zu sein.
Also wertartig im Sinne von dem, was ich jetzt auch gleich erzählen werde. Ja,
wann verwenden wir allgemein Zahlen,
Zahlen sind natürlich wichtig in der Programmierung, keine Frage,
also Zahlen als eine Form von Werten zur Identifikation, Kontonummer,
Personalnummer, zum Abzählen und Ordnen von Gegenständen, klar,
zur Repräsentation von messbaren Größen und natürlich auch in Naturwissenschaft und Technik,
alles,
was mit numerischer Analyse
zu tun hat
Das heißt, was ziemlich klar ist, alle Zahlen,
die wir so kennen, sind Werte im Sinne der Definition,
die wir uns gleich genauer ansehen werden.
Aber sind auch tatsächlich alle fachlichen Wertezahlen.
Also was ihr bisher gemacht habt, ist,
wenn ihr zum Beispiel den Betrag in unserer tollen Kinoverkaufssoftware drin habt,
habt ihr den Betrag immer den Geldbetrag über einen Int-Parameter übergeben.
Ein Betrag, ein Geldbetrag ist was anderes als ein Int,
relativ offensichtlich. Also ein Betrag zum Beispiel kann nicht
negativ sein. Dummerweise können die Ins aber auch negative
Werte annehmen
Das heißt, wir müssen uns auch so ein bisschen schon überlegen,
ja, also wir können nicht alles mit den Zahlen,
mit den primitiven Typen,
die wir in einer Sprache wie Java haben, erschlagen,
sondern wir haben irgendwie häufig auch den Anspruch,
dass diese Werttypen oder diese Werte einen fachlichen Sinn haben.
Also zu dem Anwendungsbereich passen. Postleitzahl, Bankleitzahl, klar.
Und was eben halt auch wichtig ist, diese fachlichen Werte
haben oft Operationen, die von den allgemeinen numerischen Operationen abweichen.
Also ist es zum Beispiel so, dass Kontonummern manchmal addiert werden,
ja, das passiert in Banken teilweise, um Prüfsammlungen,
Prüfsummen zu berechnen über Überweisung, werden aber nie subtrahiert.
Das heißt, man braucht auf diesem Typ Kontonummer,
braucht man eigentlich nur eine Operation zum Adieren, nie zum Subtrahieren.
Geldbeträge, die können wir addieren oder subtrahieren. Ich kann
wirklich sagen, hier Geldbetrag, minus Geldbetrag oder Plusgeldbetrag.
Man würde nie sagen, Geldbetrag, mal Geldbetrag.
Man würde höchstens sagen, Geldbetrag mal drei oder mal fünf.
Aber nicht Geldbetrag, mal Geldbetrag. Anderes Beispiel ist
auch hier in diesem Dings hier zu sehen.
Hier ist die Klasse Datum, die modelliert auch einen Werttyp.
Ich kann also jetzt hier eine Klassenoperation aufrufen.
Heute mir mal hier die Referenz auf dieses Exemplar hier,
auch meine Objektleiste. Habe also jetzt hier eine Referenz auf
ein Exemplar dieser Klasse, dass das heutige Datum repräsentiert kann.
Also hier to string aufrufen, es kommt raus, 26.6.2013. So,
jetzt kann ich hier tatsächlich sowas aufrufen wie Plus.
Ich kann also mit so einem Ding rechnen. Ich kann sagen,
heute plus sieben Tage, das ist dann der nächste Mittwoch.
So, kriege ich also wieder eine Referenz auf ein Objekt.
Okay, da sage ich mal, das ist D1. Wunderbar.
Jetzt habe ich hier ein Datum, das ist dann to string.
Der dritte siebte. Könnt ihr nachgucken. Der dritte siebte
ist der nächste Mittwoch
Man kann also wirklich damit rechnen. Ich kann auch jetzt hiermit wieder sagen,
minus, ich ziehe jetzt hier wieder sieben Tage ab und kriege wieder ein Objekt,
da sage ich jetzt mal, das ist D2. Okay,
lege ich auch hier auf meine Leiste.
Jetzt habe ich hier unten drei Referenzen auf drei Datumsobjekte.
Interessant ist jetzt aber, dass dieses Datum hier wieder der 26.06. ist.
Das heißt, ich habe jetzt zwei Objekte, die dasselbe Datum repräsentieren.
Das heißt, wir haben den Wert des Datums,
den abstrakten Wert, dieses eine Datum.
Wir müssen aber irgendwie damit umgehen, dass wir in Java
möglicherweise mehrere Objekte haben, die dieses eine Datum repräsentieren.
Das führt dazu, dass wenn ich jetzt heute mit D2 vergleiche,
dass da False rauskommt, obwohl es das gleiche Datum ist.
Logisch, weil das sind verschiedene Referenzen. Das ist genau
wie bei den Strings eben. Zwei Referenzen auf verschiedene Objekte,
die aber dasselbe repräsentieren. Aber wenn ich sage heute.equels D2,
dann kommt da True rauf, weil sie dasselbe Datum repräsentieren, denselben Wert.
Okay, also ihr seht, das ist durchaus sinnvoll,
auch mit solchen Werttypen, die man selbst konstruiert hat,
zu rechnen, dem Rahmen, der eben sinnvoll ist für den Typ,
der da gerade modelliert wird.
Nicht alle fachlichen Werte lassen sich gar nicht durch Zahn modellieren,
also wenn man so Grundfarben jetzt hat,
dann hat man gerne so eine Aufzählung und sowas wie rot-grün-blau,
die man auch verwenden kann.
Da ist eine Frage. Ja,
das ist der klassische Einwand, der an der Stelle kommt.
Man kann natürlich Farben repräsentieren im ComputerInnen mit Zahlenkurvez.
Das passiert auch der. Die RGB-Codes sind ein Beispiel dafür,
das dann tatsächlich Zahlen genommen werden. Das geht natürlich,
das ist dann die Standardisierung. Die Frage ist,
ob das das ist, was man in einem Programmierkontext immer haben will.
Aber dieses Ding würde ich inzwischen wahrscheinlich auch eher rausschmeißen,
weil es eher auf die falsche Fährte führt.
Natürlich kann man Farben auch mit Zahlen repräsentieren. Okay,
also was wir jetzt wollen, ist, dass wir ein Programm,
da sollten diese programmiersprachlichen Werte bestimmte Eigenschaften besitzen,
die sie klar von Objekten unterscheiden.
Und das ist jetzt eigentlich das, was ich jetzt in
den nächsten 20 Minuten oder zehn Minuten noch tun will.
Ich möchte jetzt Werte und Objekte als Begriffe einfach mal auseinanderfummeln.
Also einfach mal versuchen darzustellen, was haben die gemeinsam,
Woran unterscheiden die sich? Wie können wir klarer kriegen,
wann ist etwas ein Objekt und wann ist etwas ein Wert?
Weil in der Programmierung mit Java hier ganz viel mit Objekten
umgehen und ich jetzt hier aber sage, ihr braucht auch Werte.
Und Werte sind was anderes als Objekte. Ich versuche jetzt
klarzumachen, warum das was anderes ist.
Also das erste ist mal, Werte sind abstrakt.
Man kann jetzt sagen, es gibt auch abstrakte Objekte,
also so einen Knoten in einem Pass-Tree.
Ist auch was ziemlich Abstraktes, aber bei Werten ist es so,
dass sie immer abstrakt sind. Während Objekte,
wenn wir auch noch in der Modellierung bleiben,
Objekte können sein, hier so ein Mikrofon oder so
eine Hülle für eine Brille oder sonst irgendwas,
die sind also häufig materiell.
Objekte können materiell sein,
Werte sind immer abstrakt
Immer. Und die abstrahieren von konkreten Kontexten.
Also hier ist zum Beispiel mal sowas wie die zwei,
was irgendwie auch andeutet, naja, ich habe hier zwei Maiskonten,
zwei Äpfel, zwei, was immer das sein soll.
Das heißt, ich abstrahiere mit Werten tatsächlich von konkreten Kontexten.
Und das sind auch häufig Abstraktionen von Dingen, um die zu identifizieren.
Also mit einer Kontonummer oder mit einer Postleitleitzahl versuche ich halt
bestimmte Bezirke oder ähnliches oder bestimmte Personen zu identifizieren.
Was ganz wichtig ist bei Objekten ist, dass sie erzeugbar und zerstörbar sind.
Ich habe schon gesagt, in Java muss man ja immer seine Objekte mit New erzeugen.
Und auch wenn wir jetzt nicht in eine Java-Programmierung sind,
sondern einfach allgemein in der Modellierung darüber nachdenken,
wann wir Objekte sehen und beobachten, dann ist es immer so,
dass Objekte, wenn wir etwas als ein Objekt ansehen,
dann hat es die Eigenschaft,
dass es erzeugt und zerstört werden kann.
Also wenn ich irgendein Objekt B habe,
dann wird das in einem bestimmten Zeitpunkt ins Leben gerufen,
erzeugt, konstruiert, wie auch immer.
Irgendwann wird es vielleicht wieder verschrottet. Dann gibt es eine Zeitspanne auf
der Zeitachse, in der dieses Objekt in der Welt ist.
Und dann gibt es sozusagen diesen Abschnitt, das kennen ja immer die Lebensdauer,
dann gibt es den Zeitraum davor und den Zeitraum danach.
Das sind die drei relevanten Abschnitte aus Sicht eines einzelnen Objektes.
Warum unterschieden, naja, weil irgendwie das ja sein kann,
dass es andere Objekte gibt, die schon vorher gelebt haben,
in Anführungsstrichen, und dann möglicherweise dieses Objekt B beeinflusst haben.
Oder, dass das Objekt B ein anderes Objekt erzeugt hat,
das möglicherweise sogar länger lebt als das erzeugende Objekt.
Das sind alles so Dinge, darüber kann man reden bei Objekten.
Bei Werten wird man das nicht tun, weil Werte komplett zeitlos sind.
Werte, da gibt es nicht sowas wie Zeit und Dauer.
Man sagt nicht, seit dem 1.1.2009 gibt es die 40.
Damals ist die konstruiert worden, ist Quatsch. Die 40
war schon immer da. Und auch in so Ausdrücken,
wie das hier angedeutet ist, 40 plus 2 gleich 42,
da wird nicht irgendwie Ein Wert erzeugt.
Da entsteht nicht irgendwie plötzlich ein neuer Wert,
sondern das ist nur ein Ausdruck,
der ausgewertet wird und dann letztendlich ergibt, ah, das ist jetzt der WR-42.
Und das ist einer von den Werten,
die wir schon lange haben seit Ewigkeiten.
Okay, Objekte sind potenziell veränderbar. Das ist auch was,
was ihr natürlich kennt. Ein Objekt kann veränderbar sein.
Das heißt, erkennbare Magnale können sich ändern.
Und was wir auch von Objekten eigentlich so üblicherweise annehmen,
ist, dass sie ihre Identität behalten.
Also auch wenn sie sich verändern und wenn alles geändert wie
die Räder ab und neues Blech drauf und irgendwie bleibt es möglicherweise dann doch mein Auto.
Es ist immer sehr schwierig, das dann
bis zu Ende durchzudenken
Ab wann denn das nicht mehr mein Auto wäre,
wenn man alle Teile austauschen würde und so weiter.
Aber dann wird es philosophisch. Aber auf alle Fälle ist
so etwas natürlich veränderbar, während Werte unveränderlich sind. Ganz wichtig,
ich kann tatsächlich in so Berechnungen immer wieder Werte rausbekommen,
aber diese Werte, die werden nicht verändert.
Also auch hier ist es nicht so wie in Smalltalk,
dass sich der 40 die Nachricht schicke,
addiere mal die zwei auf dich selbst drauf.
Das ist einfach, sagen wir, sehr stark überobjektorientiert,
sondern tatsächlich Werte sind, unveränderlich und Funktionen können zwar darauf angewendet werden,
aber das ist immer nur applikativ.
Das heißt, die verändern da nichts dran.
Objekte sind zustandsbehaftet. Klar, wenn sie veränderlich sind,
haben sie sozusagen einen Zustand und die Veränderung eines Objekts bedeutet
auch die Veränderung seines Zustandes und diese Veränderungen finden in der Zeit statt.
Also irgendwie kann sich der Zustand eines Objektes über die Zeit ändern. Randbemerkung,
es gibt auch unveränderliche Objekte, aber das ist eher so eine Spezialbehandlung,
die wir dann nachher mal später diskutieren werden.
Wert dagegen ist zustandslos. Operationen berechnen Werte,
sie verändern sie aber nicht. Zeitbegriff trifft nicht auf Werte
Dann noch so ein paar Eigenschaften von Objekten,
die sind gut zur Kommunikation benutzbar.
Also wenn ich sowas habe wie einen Gruppenkalender,
dann kann ich da von verschiedenen Rechnern darauf zugreifen.
Dann ist es nützlich, dass man diese Idee hat von jemand
ändert etwas in diesem Gruppenkalender und jemand anders kann das dann auch sehen.
Also das dient also auch zur Kommunikation, zur Kooperation.
Das heißt, solche Seiteneffekte, die andere beobachten können,
die können schwierig sein, müssen aber nicht schwierig sein.
Was bei Objekten auch besonders ist, ist,
dass es einen Unterschied gibt zwischen Gleichheit und Identität.
Also zwei gleiche Objekte,
hier so zwei Bücher
Die sind möglicherweise gleich. Gleicher Verlag, gleicher Titelgleich ist
alles gleich. Aber es sind trotzdem zwei verschiedene Objekte.
Die sind nicht identisch. Also Gleichheit ist eigentlich ein Begriff,
der sich auf erkennbare Merkmale bezieht, also auf Titel,
Autor, Seitenzahl, was weiß ich was.
Signatur. Während die Identität eigentlich eher so auf die äußeren
Zusammenhänge abzielt. Also es kann immer nur ein Objekt zu
einer bestimmten Zeit an einem bestimmten Ort sein.
Also wenn ich die beiden Bücher jetzt hier hinlege,
dann kann ich nicht dafür sorgen, dass das zweite Buch,
was hier liegt, zur gleichen Zeit am gleichen Ortlicht.
Das geht nicht. Das geht nicht. Das ist also
physisch nicht möglich. Ich kann aber natürlich die vertauschen, die Bücher.
Und dann ist es tatsächlich so, dass das eine Buch,
was vorher noch da war, jetzt da liegt.
Also Zeit und Raum spielen durchaus eine Rolle,
wenn man sozusagen über Identität reden will.
Aber der Identität, Identitätsbegriff ist auch wieder was,
wo man sehr stark ins philosophische abschweifen kann,
will ich an dieser Stelle gar nicht.
Okay, und dann noch Objekte sind potenziell kopierbar.
Also wir haben eigentlich immer so eine Idee von,
das weiß ich, einen Vertrag in einer Versicherung.
Da kann man sich vorstellen, da gibt es eine Kopie davon.
Aber von Werten wird man keine Kopien haben.
Also es ist irgendwie komisch zu sagen,
ich kopiere die vier oder die
Ich kann natürlich verschiedene Repräsentationen der 42 haben.
An verschiedenen Stellen kann ich auf die 42 verweisen.
Aber ich würde nie sagen, ich kopiere die 42 selbst.
Und der Begriff Anzahl ist auf einen Wert eigentlich nicht anwendbar.
Also wie viele gibt es denn von diesem Wert? Okay,
das heißt, wenn wir das jetzt mal,
was ich bis jetzt gesagt habe, zusammenfassen,
dann können wir sagen, ein Wert ist abstrakt,
also immer abstrakt, das ist immer zeitlos und es ist immer unveränderlich.
Während Objekte, die können zustandsbehaftet sein, also potenziell veränderbar,
es gibt auch welche, die nicht zustandsbehaftet sind.
Auf alle Fälle sind Objekte erzeugbar und zerstörbar.
Das heißt, sie haben eine Lebensdauer
Okay. Was ich jetzt so ein bisschen hier versucht habe anzudeuten,
ist, dass Werte und Objekte beide wichtig sind,
also dass das Grundkonzepte sind, die wir in der Softwareentwicklung brauchen.
Und dass es hilft, wenn ich einen bestimmten Anwendungsbereich modellieren will,
also wenn ich irgendwo in einem Anwendungsbereich Software entwickeln will,
dann hilft es mir,
wenn ich beide Konzepte kenne und auch beide als gleichwertig anerkenne.
Also tatsächlich mir überlege, will ich das jetzt als Wert
oder als Objekt modellieren? Wenn ich das aber richtig modellieren will,
dann sollte ich diese Unterschiede sehr gut kennen.
Deswegen haben wir das jetzt hier so ein bisschen thematisiert.
Der nächste Schritt ist dann eigentlich, inwieweit unterstützt mich denn
die Programmiersprache, die ich verwende?
Dabei sowohl Werte als auch Objekte gut abzubilden. Also tatsächlich,
wie gut machen die aktuell verwendeten objektorientierten Sprachen das?
Also das ist jetzt momentan hier immer noch, ja,
SE2, also objektorientierte Programmierung und Modellierung.
Das ist noch nicht funktionale Programmierung. Aber wir können schon
mal so ein bisschen gucken, wie sieht das denn aus,
wenn ich in einer objektorientierten Sprache sowas versuche,
wie Werte mit zu modellieren.
Okay, es gibt soweit erstmal Fragen zu dem,
was ich jetzt gerade erzählt habe.
Das ist soweit ganz gut nachvollziehbar. Ich habe jetzt einfach
so ein paar Begriffe hier in den Raum gestellt.
Dann sind wir heute relativ früh dran. Das heißt,
wir könnten jetzt mal eben fünf Minuten Pause machen
Rum? Also bitte wieder auf die Plätze begeben,
damit alle wieder in Ruhe zuhören können. Prima,
also, ich habe jetzt motiviert, Vertonobjekte sind wichtig,
Werte und Objekte, also nicht nur Objekte.
Und die Frage ist jetzt, wie machen das denn
die Objekte notierten Sprachen mit ihrer Unterstützung für Werte?
Was wir kennen aus einer Sprache wie Java ist,
dass man mit einem Klassenkonstrukt, also mit diesem Schlüsselwort Klaas,
beliebige Objekttypen definieren können.
Ihr könnt ja einfach neue Typen definieren, die man einfach sagt,
klar ist Person und dann definiert ihr die Eigenschaften einer Person
und dann habt ihr einen neuen Typ, einen neuen Objekttyp.
Wir nennen das auch einen Typkonstruktor,
dass man also mit diesem Glas-Mechanismus neue Typen konstruieren kann.
Wenn wir jetzt auf Java gucken, dann ist es so,
dass die Werttypen festgelegt sind. Also die Typen,
die sich wertartig verhalten, sind einfach genau hier Int-Byte,
Shortlong, Float Double, Bullyen und Chart.
Das sind genau acht. Und diese Menge an Typen,
die sich ganz klar wertartig verhalten. Bei String muss man ja aufpassen.
Das ist ja so, eigentlich ist es was Wertartiges.
Ich hätte es gerne, als was rein Wertartiges,
aber es ist noch, es schimmern noch die Objekte durch.
Da ist es einfach festgelegt. Also Java ist in der Hinsicht
nicht flexibel. Es ist total flexibel Objekttypen zu definieren.
Es ist überhaupt nicht flexibel, Werttypen zu definieren,
die so genauso sind wie Indbite und so weiter.
Jetzt kann man natürlich fragen, was ist doch eigentlich eine Programmiersprache,
die relativ neu ist? Also erst seit 20 Jahren auf
der Welt. Warum haben die das denn so blöd gebaut?
Warum gibt es so wenig Unterstützung für benutzerdefinierte Werte.
Warum sind Werte so unterpräpräsentiert? Naja,
und da kann man natürlich wieder sagen,
muss man auf diese Entwicklung von Programmiersprachen ein bisschen mit drauf schauen,
dass es eine gewisse Tendenz gab, puristisch zu entwerfen.
Also die Sprachen so zu bauen, dass sie pur sind,
pur objektorientiert. Also zum Beispiel Smalltalk gilt als eine der
pur objektorientierten Sprachen. Da ist wirklich alles ein Objekt.
Klassenwerte, Blöcke innerhalb des Quelltextes, das sind alles Objekte.
Man kann jedem Objekt eine Nachricht schicken,
das ist also
ganz voll durchgezogen
Eifel ist eine Programmiersprache, die auch relativ bekannt war in den 80ern und 90ern.
Zumindest zur Laufzeit gab es da nur Objekte, es gibt
nichts anderes. Keine Klassenobjekte oder ähnliches wie in Java.
Und die absolute, der puristischste Ansatz, was Objektantieren angeht,
ist in der Sprache self umgesetzt worden.
Die haben Objektorientierung so weit geführt, dass es gibt nur
noch Objekte, es gibt auch keine Klassen mehr.
Also diese Idee von, eine Klasse ist eine Schablone für
Objekte, rausgekickt. Es gibt nur noch Objekte,
ich definiere ein Objekt und wenn ich davon mehrere haben will,
dann muss ich das halt klonen.
Das sind also
exemplarbasierte Sprachen
Und das ist ganz interessant,
wenn man sich das jetzt mal so anguckt,
wie so die Welt der Programmiersprachen so sich entwickelt hat,
dann kann man da so ein Spektrum aufmachen,
so sozusagen am linken Rand sind die Sprachen,
die nur Werte kennen, also die nur mit Werten umgehen,
gar keine Objekte haben oder weniger Objekte.
Auf der rechten Seite sind die Kandidaten, die praktisch nur mit Objekten umgehen.
Und wenn man da jetzt mal so hier die Zeitachse von oben nach unten sieht,
dann sieht man so, Lizb ist so einer der Urfahrt,
Urväter von allen Programmiersprachen, eher so funktional ausgerichtet,
dann sieht man hier rechts sozusagen die Schiene der objektorientierten Sprachen,
Simular als Vorreiter, dann Smalltalk, Affiliate Self,
Self ist sozusagen hier am rechten Rand.
Das ist sozusagen die purste Objekt- und Titelsprache, die man sich vorstellen kann.
Auf der anderen Seite gibt es eben halt so Sprachen wie Skien,
ML, Miranda und dann sozusagen auch da interessant,
relativ zeitgleich ausgeforscht, beide Rente des Spektrums.
Haske, die purste, funktionale Sprache, die es gibt.
Es gibt überhaupt keine Zustände in der Sprache, abgeschafft.
Alles nur noch funktional. Das ist also, das ist
toll. Witzigerweise gibt es aber keine größeren Systeme,
die in Haske oder in Self gebaut sind.
Das liegt vielleicht daran, dass die zu puristisch sind.
Die versuchen wirklich, das sind Forschungssprachen, die haben den Rand ausgeforscht,
aber Die realen Systeme werden dann doch in anderen Sprachen gebaut.
Und zwar ist es ja so, wenn wir jetzt auch,
macht ja Sinn, wenn ich sage,
man braucht sowohl Werte als auch Objekte,
man braucht also Zustände und auch zustandsfreie Dinge,
dann muss man irgendwas haben, was das kombiniert.
Das ist genau das, wo dann hier die pragmatischen Sprachen sich tummeln,
also so wie C Plus Plus oder Ceelers, C-Sharp,
Java, eher noch objektorientiert, ja, möglichst pur objektorientiert.
Sie Sharp schon sehr viel pragmatischer, auch so funktionale Aspekte
mit drin. Und Skala ist eine relativ neue Sprache,
die das wieder versucht, eigentlich das Beste aus beiden Welten
Ja, also man sieht, das ist eine ganz spannende Frage.
Wie braucht man Werte, braucht man Zustände? Da braucht man Objekte.
Und wenn wir jetzt hier bisher objektantierte Programmierung vermittelt haben,
könnte man ja sagen, naja, wir haben ja gesagt,
alles, man könnte ja sagen, alles nur Objekte.
Also pur Objekte und hier ist es super. Ja,
da hat man ein einfaches Sprachmodell,
da hat man keine Sonderregeln mehr mit,
wie die mit primitiven Typen in Java, konsistente Semantik,
insbesondere bei Variablen, nicht wie diese komische Unterscheidung zwischen Referenzvariablen und diesem Wertvariablen in Java,
einheitliche Generizität.
Die kann ja in Java eigentlich keine List of Int machen,
sondern nur List of Intiger
Alles so ein bisschen hässlich. Also wenn alles Objekte wären,
wäre es viel einfacher. Die Sprache wäre viel orthogonaler, viel klarer.
Kann man jetzt sagen, das sind Primärargumente für Sprachdesigner.
Natürlich kann man auch sagen, auch für Programmierer wäre das einfacher.
Tatsächlich ist das aber die falsche Annahme. Zumindest ist es
unsere These. Wir sagen halt, man braucht beides.
Und wenn ich in einer Sprache gezwungen werde,
alles mit Objekten zu modellieren, dann verbiege ich mich ziemlich bei den Werten.
Und das ist das, was wir in Java auch beobachten,
wenn ich damit Werte versuchen will zu modellieren,
dann fällt das relativ schwer.
Dann fange ich nämlich an, hier so eckige Klötze in Runde Löcher zu stecken.
Und das ist meist nicht so vorteilhaft. Das ist was,
was die Engländer gerne Putting as Square Pack into around hole nennen.
Gut. Also, jetzt mal ein bisschen darüber gesprochen,
wie das denn in Programmiersprachen abgebildet wird, so mit Werten und Objekten.
Das mit den Objekten, das kennen wir. Also in
der UO-Sprache modellieren wir Objekte, indem wir Klassen definieren.
Und von diesen Klassen können wir Exemplare erzeugen. Also in
der Sprache wie Java ist das auf jeden Fall so.
Und wir wissen auch, dass jede Klasse ein Typ definiert.
Und wir wissen ja immer, ein Typ,
das ist so eine Zusammenfassung von Elementen
Also so Elementen des Typs und den Operationen darauf. Das heißt,
die Operationen der Klasse sind auch die Operationen des Typs.
Und die Exemplare einer Klasse bilden extensional die Elementmenge ihres Objekttyp.
Das heißt, ich sage einfach,
wenn ich ein Klasse Konto habe und 20 Konten habe,
dann habe ich in der Wertemenge oder in der Elementmenge von diesem Typkonto 20 Elemente,
20 Werte in der Wertemenge.
Ich habe jetzt hier so ein bisschen unscharf Wertemenge gesagt, Elementmenge.
Wir machen das jetzt mal explizit das. Wir sagen,
wir nennen diese Menge, die zu einem Typ gehört,
nicht mehr Wertemenge, weil wir über Werte und Objekte reden,
wäre es ja blöd,
wenn wir das unscharf halten
Wir das Elementmenge. Also Element ist der Oberbegriff für Wert und Objekt
, einfach um es ein bisschen klar zu halten hier.
Also das sind Werte und Objekte, sind Elemente ihres Typs.
Okay. Und wenn wir jetzt uns das bei den Werten angucken,
da auch mal überlegen, wie sind denn da die Werttypen dazu abgebildet?
Also ein Wert wie eine ganze Zahl oder ein Wahrheitswert wie
True of Falls, die werden ja durch Werttypen modelliert.
Also da gibt es einfach auch einen Typ Int oder Bulien.
Und da ist es ganz interessant, die Elementmenge, dieser Typen ist unveränderlich.
Das heißt, Bei Bulien ist es ganz offensichtlich,
es gibt nur genau zwei Werte, zwei Elemente dieses Typs,
nämlich True and Force und nichts weiter.
Und da kann man auch nicht versuchen, irgendwelche zu erzeugen oder so.
Die Wertemenge ist festgelegt. Oder die Elementenmenge.
Und die Elementmenge ist auch bei Int festgelegt in Java.
Das sind einfach 2 hoch 32 Elemente.
Die sind einfach da und das kann man auch nicht vergrößern.
Und das ist, passt aber eigentlich ganz gut dazu,
was wir gesagt haben. Wenn ich mir überlege,
Wert wird nicht konstruiert und Wert wird nicht erzeugt.
Na dann ist es ja logisch, dass die Wertemenge eines Werttyps stabil ist.
Die kann sich ja nicht ändern. Weil es kommen ja
keine dazu, weil es werden ja keine erzeugt.
Die können auch nicht vernichtet werden. Also die sind einfach
Fix. Und deswegen ist es auch so,
dass wir bei Werttypen eigentlich ungern von Konstruktoren reden.
Wir sagen nicht, für einen Werttyp gibt es einen Konstruktor,
sondern eigentlich ist es ein Selektor.
Wir selektieren aus der schon vorhandenen Menge von Elementen,
von Werten einen und sagen, den möchte ich jetzt haben.
Ich möchte jetzt die 42 haben oder ich sage,
ich möchte 3 plus 7 haben und dann ergibt das die Zähne und
dann wird die Zähne aus dem Pool von meinen Elementen einfach rausgeholt.
Also wir selektieren eigentlich Werte aus bestehenden Wertemengen. So,
ja, jetzt kommen wir wieder in die Zusammenfassung, Zwischenstand.
Also wir haben schon gesagt,
Wert ist abstrakt zeitlos unveränderlich und Objekt kann einen Zustand haben
und das auf jeden Fall hat eine Lebensdauer
In Programmiersprachen sind die definiert über Wehrtypen,
mit einer unveränderlichen Elementmenge, die Selektoren anbieten sollten und Objekttypen,
die haben eine dynamische Elementmenge und die bieten Konstruktoren an,
um neue Objekte zu erzeugen.
Und gemeinsam ist, wenn wir den Typbegriff hier,
den wir ja in der SE1,
in der SE2 schon mehrfach gehört haben,
also Typ ist eine Elementmenge plus Operationen auf diesen Elementen
und natürlich kann ich auch von einem Typ Variablen deklarieren.
Mit veränderbarer Belegung in den funktionalen Sprachen wird es dann auch Variablen geben,
wo man sagt, die können nicht veränderlich belegt werden.
Auch in Java kann man eine Variable als Final deklarieren,
dann kann man
sie auch nur einmal belegen
Okay. Eine Sache hatte ich vorhin schon gesagt,
was die Gleichheit angeht. Da habe ich gesagt,
bei Objekten kann man unterscheiden zwischen Gleichheit und Identität.
Und das ist tatsächlich wieder so ein Punkt, wo man
auch in Programmiersprachen den Unterschied sehr deutlich sieht, Zwischenwerten und Objekten.
Also in Java, was bedeutet A, gleich gleich B?
Wir wissen jetzt, da muss ich darauf aufpassen,
was für ein Typ das Ding hat. Also A,
gleich gleich B, ist nicht jetzt sofort beantwortbar,
wie man das lesen muss. Also ich kann euch nicht sofort sagen,
was das ist, weil ich muss erst wissen,
ist A, ein Int, dann hier irgendwie A,
gleich gleich B,
also sowas hier
Wenn A, ein Int ist,
dann ist das wahrscheinlich relativ klar, dass da tatsächlich am Ende,
wenn A und B jeweils 42 zugewiesen wird,
am Ende auch A, gleich gleich B ist.
Aber was ist mit Strings? Haben wir gerade das Beispiel gesehen,
Strings? Da ist es mit dem Gleichgleichvergleich dann wieder blöde,
weil man dann eigentlich die Referenzen vergleicht und nicht die referenzierten String-Objekte.
Okay, also da sieht man schon den Unterschied.
Gleichheit ist tatsächlich so ein relativ heiß diskutiertes Thema.
Es gibt tatsächlich da ganze wissenschaftliche Abhandlungen drüber.
Und da gibt es zum Beispiel ein Paper,
da werden so technisch drei Formen unterschieden,
so gerade in Objekten undtierten Sprachen,
Identität wird das auch genannt. Also ich habe hier zwei Variablen,
A und B und die verweisen auf dasselbe Objekt.
Also das ist sozusagen das referenzierte Objekt ist identisch zwischen diesen beiden Variablen.
Die Referenzen sind gleich. Die Referenzen zeigen auf dasselbe Objekt
. Dass hier dann irgendwie noch so eine Substruktur hat.
So, einfache strukturelle Gleichheit ist sowas wie,
ich habe zwei Variablen und die sind oberflächlich gleich.
Also die Objekte hier, auf die verwiesen wird.
Also das sind immer Objekte hier mit so einem gekapselten Zustand.
Die sind gleich und die haben dann irgendwie eine Unterstruktur
und sind also tatsächlich auf oberster Ebene gleich.
Und dann gibt es noch sowas wie rekursive, strukturelle Gleichheit. Also wirklich,
ich habe zwei Variablen und dann vergleiche ich sozusagen die ganze Struktur,
ob da immer gilt, dass die darin abgelegten Dinge gleich sind.
So, und das ist klar, wenn ich Identität habe,
dann impliziert das natürlich flache Gleichheit oder einfache strukturelle Gleichheit.
Und das wiederum impliziert natürlich dann auch,
dass dann auf tiefenmäßig alles gleich ist.
Wunderbar, toll, kann man technisch alles machen,
kann man implementieren in Sprachen.
Also Smalltalk hat diese ganzen verschiedenen Gleichheitsformen zum Beispiel
Ja, aber jetzt ist das die Frage, ist das ausreichend?
Also wenn ich so ein Bibliotheksbuch habe,
Titelautor, ISBN-Referenznummer, kann ich als gleich ansehen,
auch wenn die Referenzen nochmal unterschiedlich ist?
Also ich habe tatsächlich dasselbe Buch mehrfach da mit unterschiedlichen Referenznummern.
Wenn ich in die Bibliothek gehe, ist mir wurscht,
welches von den dreien, die da sind, ich bekomme.
Für mich sind sie gleich. Aus Sicht der Bibliothek
sind sie verschiedene Exemplare. Für mich sind sie gleich.
Das heißt, Gleichheit ist auch eine Frage des Standpunkts.
Also wer will gerade irgendwas vergleichen, für welchen Zweck?
Und deswegen gibt es immer auch so eine Idee von semantischer Gleichheit,
wird das häufig genannt,
also die
für den Kontext relevant ist
Also könnte man da sagen, na gut, gibst du
auch in Java? Ich kann doch mit Equills,
kann ich doch definieren, wie Objekte gleich sind.
Ich habe das genau die Möglichkeit zu redefinieren für meinen neu definierten Typ,
wann Exemplare in meiner Klasse auch als gleich gelten sollen.
Ja, klar kann man machen, aber es ist die Frage,
ob das nur eine gute Lösung ist. Also ihr wisst,
dass Equills insbesondere in Java ist ziemlich hässlich, erstens ist es asymmetrisch.
Ich muss also an dem einen Objekt aufrufen,
Equils ein anderes Objekt, das ist nicht symmetrisch,
das ist schon dann nicht symmetrisch, wenn eins von beiden Nall ist.
Ich kann auch ein Objekt fragen, ob es gleich ist,
Equils Null, das kann funktionieren,
da kann das Objekt entweder sagen,
ja,
fühle mich
dem gleich oder nicht
Aber ich glaube, umgekehrt, wenn ich jetzt über eine Nahreferenz
eine gültige Objektreferenz übergebe und da E-Codes aufrufe, dann kracht es halt.
Also das ist schon mal nicht symmetrisch.
Welchen Typ hat der Parameter? Ihr wisst, in Java
, gibt man da als Parameter bei E-Quills an Object.
Das führt zu diesen wunderbar hässlichen Downcasts, wenn man dann tatsächlich das E-Quills implementieren will.
Das kennt ihr auch. Wenn man das nicht will,
wenn man da versucht, irgendwie sowas zu bauen,
wie in Eifel, die haben gesagt,
ah, der Typ ist eigentlich der gleiche wie von,
also ich habe eine klasse Person und die hat eine Operation E-Quills und der Parameter soll nicht Person sein,
sondern der gleiche Typ wie die Klasse,
in der das definiert ist.
Wenn das dann redefiniert wird, also ich erbe einen klassischen Student,
dann wird das Equals automatisch zu einem Equals,
das einen Student als Parameter erwartet.
Super Idee, haben die einen Eifel sich wirklich gut überlegt,
ging nur leider überhaupt nicht gut aus,
weil dadurch die Sprache nicht statisch typsicher war.
Das ist eine Co-Variante Parameter-Typ-Änderung. Das habe ich vor ein
paar Vorlesungen schon erzählt, dass das nicht statisch typsicher ist.
Also da gibt es eine ganze Menge Probleme. Hier nochmal
so ein kleines Ding, was ihr aus Java vielleicht euch
nochmal angucken könntet. Also Gleichheit ist ja mathematisch formuliert,
reflexiv, also Identität impliziert Gleichheit,
haben wir
ja eben schon gesehen
Wenn A gleich B ist, dann gilt auch B gleich A.
Also das ist eine symmetrische Relation.
Und wenn A gleich B gilt und B gleich C,
dann gilt auch transitiv, dass A gleich C ist.
So ist mathematische Gleichheit üblicherweise definiert. Jetzt gucken wir uns
das mal an, wie das in Java ist.
Seit es Java 1,5 gibt. Ich habe eine Variable A
vom Typ Integer und weise 128 zu.
Was da passiert ist, die 128 wird in ein Objekt verpackt,
weil das ja ein Objekttyp ist, Integer.
In B kriegt hier die 128 direkt zugewiesen.
Und Integer C wird wieder die 128 eingepackt in ein Integer Objekt
So, jetzt gilt, A, gleich, gleich B.
Das ist in Java so definiert. Denn tatsächlich ist es so,
wenn hier das A mit dem B verglichen wird,
dann stellt der Compiler fest, oh,
das eine ist ein Intit-Shot, das andere ist ein Int,
dann packe ich den Ittager mal aus.
Das nennt sich da ein Auto, Unboxing. Es wird
also ausgepackt, der Wert. Und dann werden die Werte verglichen.
Genauso wenig BMEC vergleiche, stell dir wieder fest, oh,
einer ist ein Int, der andere ist ein Intiter,
packe ich den einen aus und dann kann ich wieder vergleichen.
Dumm ist nur, wenn beides Integer sind, dann macht er einen Referenzvergleich.
Und dann werden tatsächlich wieder zwei gleiche Werte Zwei gleiche Objekte,
die den gleichen Wert repräsentieren, als unterschiedliche Objekte angesehen.
Ziemlich hässlich und nicht so schön. So,
was auf jeden Fall erstmal wichtig ist, ist,
dass wir bei Objekten tatsächlich so eine Unterscheidung haben zwischen Gleichheit und Identität.
Die haben wir bei Werten nicht. Ob ihr fragt,
ob eine Zahl gleich einer anderen ist oder ob es die
gleiche oder dieselbe Zahl ist, das ist euch wurscht.
Man unterscheidet sowas bei Werten nicht. Bei Objekten schon ein Unterschied.
Gut, also haben wir jetzt noch hier mit aufgenommen.
Wir unterscheiden bei Objekttypen Gleichheit und Identität
Jetzt haben wir sozusagen eigentlich das Ganze schön auseinandergefummelt.
Wir wissen jetzt, was Werte, was Objekte sind,
was so die Eigenschaften sind. Wir haben noch diesen kleinen
Aspekt mit den unveränderlichen Objekten. Zum Beispiel in dieser Mediathek,
die wir ja euch ja schon haben programmieren lassen,
kann man ja Filme modellieren, als Dinge, die im Konstruktor begibt,
wird der Titel der Regisseur und die Filmmlänge gesetzt.
Und danach bleibt das Objekt unveränderlich. Man kann also nur noch
mit Ghettern sozusagen auf diese Operation, auf diese Dinge zugreifen.
Ja, dann könnte man ja jetzt sagen,
ist das denn, wenn ein Objekt ausschließlich sondierende Operationen anbiet,
ist es da nicht eigentlich ein Wert
Und jetzt kann man wieder mit den konzeptuellen Eigenschaften kommen,
die wir ja jetzt hier aufgetischt haben. Nee,
also wenn ein Wert, ein Wert sein will oder ein Werttyp,
ein Werttyp sein will, dann muss er tatsächlich alle konzeptionellen Eigenschaften erfüllen.
Und bei dem Film ist es nun wieder so, naja,
ein Film mag ja unveränderlich sein, aber der ist nicht zeitlos.
Das heißt, ein Film wird irgendwann erzeugt. Es gibt garantiert einen Zeitpunkt,
wo es den Film noch nicht gab und dann ab
dem Zeitpunkt ist der Film in der Welt.
Also da merkt man schon wieder, wenn man dieses Konzept
von Zeitlosigkeit akzeptiert, dann passt das hier nicht.
Also es gibt tatsächlich sowas wie unveränderliche Objekte, die sind auch sehr nützlich.
Okay, jetzt so ein bisschen der Blick nach vorne,
was wir gerne hätten, was wir auch tatsächlich selber erforschen,
ist, dass man eigentlich in einen Programmiersprachen gerne beides hätte.
Also neben dem Glass-Konstrukt, um Objekttypen zu definieren,
hätten wir gerne auch ein Value-Class-Konstrukt, also einen Konstruktor,
um Wehrtypen zu definieren,
die wirklich dann diese Werttyp-Eigenschaften auch alle einhalten
Ja, da muss dann irgendwie alles erfüllt sein.
Also die Wertemenge muss fixiert sein, man kann keine Werte erzeugen oder zerstören.
Die Elemente müssen unveränderlich sein und die Operationen sollten referenziell transparent
sein und keine beobachtbaren Seiteneffekte haben. Das sind Konzepte,
die ihr besser versteht, wenn ihr funktionale Programmierung intensiv gemacht habt.
Dann kommen diese Eigenschaften klarer raus, was das bedeutet.
Aber so keine Seiteneffekte ist klar, also ich möchte in
einem Werttyp nicht, dass dann irgendwie Objekttypen verändert werden.
Und außerdem kann es nicht sein,
dass ein Werttyp auf der Basis eines Objekttyps definiert wird.
Das wäre irgendwie komisch, so ein zeitloses,
elegantes Ding wie ein Werttyp wäre in seiner Definition basierend auf etwas,
was irgendwie erst spät in die Welt kommt.
Also das ist irgendwie, das kann eigentlich nicht zusammengehen.
Also es wäre komisch, wenn Wehrtypen von Objektypen abhängig sind.
Deswegen in unserer Hierarchie ja auch ganz klar,
die ganzen Objektypen können durchaus auch Werttypen verweisen, aber nicht umgekehrt.
Da war eine Meldung da hinten gerade, eine Frage.
Ja, die ist jetzt machst du durch diese Regelung.
Ah, okay, sie fragt,
ob das jetzt nicht die Lücke schließt mit den Enums.
Auf die Enums komme ich gleich.
Auch die Enums komme ich gleich. Die Enums sind wieder
speziell in Java. Zufällig komme ich da jetzt drauf
Ja. Okay, jetzt dritter Teil. Juhu, wir
haben noch ein bisschen Zeit. Das ist sehr schön.
Ich habe jetzt gesagt, Werte und Objekte sind wichtig.
Ich möchte Werte auch irgendwie haben. Dann habe ich ein bisschen fabuliert,
wie denn das vernünftig aussehen könnte in einer Programmiersprache,
wenn es unterstützt würde.
Jetzt sind wir wieder in der Realität, ja, plumps gelandet.
Wir müssen mit Java programmieren. Wir wollen mit Java
auch Werttypen modellieren können. Und dann müssen wir natürlich
mit dem Bordmitteln arbeiten, die wir haben.
Also in Java gibt es
nur Objektklassen
Und wenn wir Werttypen modellieren wollen, in Java,
dann müssen wir das mit Klassen tun.
Aber die nennen wir jetzt ab sofort Wertklassen. Also wenn
eine Klasse dafür da ist, einen Werttyp zu modellieren,
nennen wir es eine Wertklasse. Und dann wollen wir eben mal
darauf achten, dass diese Werteigenschaften eingehalten sind in der Programmierung.
Da gibt es einige Programmiermuster dazu und ein relativ prominentes Beispiel ist,
dass Type safe ihn am Pattern von Bloch,
das wieder aus diesem Buch ist, wie gesagt,
dass ich gar nicht oft genug empfehlen kann.
Type safe inneren Pattern ist eigentlich relativ einfach. Das beschreibt
wie Aufzählungstypen, Typ sich ja in Java modelliert werden können.
Aufzählungstypen, die gerade schon nachgefragt wurden, sind eigentlich auch ein Werttyp.
Also wenn ich sowas habe, wie rot-grün-blau,
so ein Aufzählungstyp mit drei Farben, dann habe ich genau diese Eigenschaften,
die Elemente sind unveränderlich, die Wertemenge ist festgelegt,
genau wie das für Werttypen haben wollen.
Prima, prima. Wie baut man das in Java?
Naja, man hat eine Klasse und macht einen Konstruktor,
der private ist. Das heißt also,
ein Klient von dieser Klasse kann erstmal keine Exemplare mehr erzeugen.
Damit ist schon mal garantiert, dass es nur die Exemplare
gibt, die innerhalb dieser Klasse erzeugt werden
Und man sieht hier, dieser private Konstrukt,
da wird hier dreimal aufgerufen, nämlich einmal für rot,
einmal für grün, einmal für blau.
Und diese Objekte, die da erzeugt werden,
die Referenzen darauf werden dann diesen öffentlichen Klassenkonstanten zugewiesen.
Das heißt also, es gibt dann Farbe Rot, Farbe grün,
Farbe blau und die werden einmal zugewiesen und sind danach nicht mehr änderbar.
Das heißt, es gibt genau drei öffentliche Referenzen und die verweisen auf diese drei Elemente.
Das heißt, ich habe genau einen Typ definiert mit festgelegt
drei Elementen und kann nur mit denen eigentlich nicht viel machen.
Ich kann hier noch to string aufrufen und vielleicht noch Hashcode,
was weiß ich was, was man da noch dazu bauen will.
Das ist also relativ einfach, so was zu bauen.
Und tatsächlich ist das Muster hier, wie es hier dargestellt
ist, dann auch in Java eingeflossen. Das heißt,
die Enums, die ihr in Java ja definieren könnt,
die sind genau nach diesem Muster gebaut.
Hinter den Kulissen passiert genau das. Da wird noch von
einer Enum-Klasse geerbt zusätzlich, aber das sind so Randbedingungen.
Warum die Enums in Java nicht wirklich waschechte Werttypen sind,
das liegt daran, dass mit diesem Enum-Konstrukt,
in Java, man auch veränderlichen Zustand modellieren kann.
Also diese Exemplare hier können durchaus auch Operationen anbieten,
an denen der Zustand eines Objektes geändert werden kann, eines Exemplars dieser Klasse.
Das geht, Java hat es sozusagen flexibel gemacht.
Das ist also einfach nur ein technisches Konstrukt. Man muss nur einfach wissen,
dass mit Enhums nicht automatisch Werttypen definiert werden,
sondern man kann mit Enhums sehr elegant und knapp einfache Werttypen definieren, Aufzählungstypen.
Aber man kann damit genauso auch Objekttypen definieren, muss man so aufpassen.
Gut, ja. Und was dann entsteht, sind Wertobjekte,
also von diesen Wertklassen, habe ich ja gesagt,
wenn eine Klasse einen Werttyp modelliert,
wir es eine Wertklasse und dann entstehen Wertobjekte,
also fachlich motivierte Werte, die wir technisch bedingt einfach,
weil es in Java nicht anders geht, mit Objekten repräsentieren müssen.
Ja, das war auch genau das, was wir
hier gerade gesehen hatten. Ich habe hier technisch Objekte,
die aber repräsentieren, eigentlich Werte. Okay, und jetzt
haben wir einfach hier nochmal so ein paar Richtlinien dazu,
wie man solche Wertklassen in Java bauen kann.
Ist eigentlich gar nicht so groß kompliziert.
Man hat so ein paar Regeln bei der Konstruktion.
Also wie definiere ich denn solche Wertklassen?
Und dann eine Regel noch bei der Benutzung,
die auch
nicht immer unbedingt greifen muss
Die Regeln sind hier, erstens, dass die Wertobjekte
keinen veränderbaren Zustand haben dürfen. Macht Sinn. Wir haben
ja gesagt, die Elemente von Werttypen haben keinen Zustand.
Das Werte- und Wertobjekte sich nicht auf Objekte beziehen,
also dass wir keine Abhängigkeit haben von Werten zu Objekten.
Dass im Quelltext einer Wettklasse keine bestehenden Objekte verändert werden,
also dieses Seiteneffekt frei, wenn ich im Rumpf einer Klasse,
einer Wertklasse irgendwie Objekte verändern könnte, würde ich ja einen Zustand ändern.
Dann würde sozusagen als Seiteneffekt irgendwas verändert werden,
dass wir nicht damit zusammenpassen,
dass eigentlich Werttypen zustandslos sein sollen und auch
nichts verändern sollen
Und Equals und Hashcode muss man entsprechend implementieren.
Und wir wollen auch diese technisch notwendige Erzeugung,
also wir müssen ja in Java immer Exemplare erzeugen,
aber die sollte man eigentlich verbergen.
Okay, das ist einfach hier nochmal ein bisschen aufgeschlüsselt.
Ich habe das jetzt hier so ein bisschen so dargestellt,
also erstmal, was will man erreichen und was für eine Sprachunterstützung haben wir dafür.
Und die erste Regel ist, die Wertobjekte von Wertklassen sollen unveränderlich sein.
Kein Problem. Da gibt es gleich zwei tolle Unterstützung in
Java. Ich kann mit Final für die Zustandsfelder festlegen,
dass sie unveränderlich sind. Das heißt, ich kann die
nur im Konstruktor
einmal zuweisen
Das heißt, damit kann ich schon mal eine gewisse Sicherheit erreichen,
dass da nicht irgendwie dann aus Versehen was geändert wird an
so einem Zustand von so einem Wertobjekt.
Und ich kann aber auch mit dem Schlüsselwort Final für die
ganze Wertklasse festlegen, dass es keine Subklassen geben darf.
Sonst könnte man sich ja überlegen,
ich habe diesen Typ, was weiß ich, Datum,
kann mir eine Variable vom Typ-Datum deklarieren.
Jetzt kommt jemand daher und ist schlau, objektorientiert.
Ich mache einfach eine Unterklasse von Datum.
Und da sind die Dinge dann irgendwie veränderlich.
Und die schummel ich dann polymorph. Ja,
weil das ist ja ein Subtyp, da drunter,
wo hier
irgendwie Dattümer erwartet werden,
Ja, und dann hat man plötzlich veränderbaren Zustand über eine Variable,
wo man eigentlich was Unveränderliches erwartet. Deswegen gibt es üblicherweise
keine Vererbung für Wertklassen. Das kann man eben halt festlegen,
indem man einfach in der Wertklasse sagt, die ist Final.
Das kann man auch mal hier zeigen,
dass diese Datumklasse hier, die hier gebaut ist,
im Quelltext tatsächlich genauso aussieht.
Da sieht man hier Final Class Datum und dann hat man hier Jahr,
Monat und Tag,
sind auch Final deklariert
Okay, das ist also tatsächlich, da gibt es Sprachunterstützung,
sehr schön, dann Wertobjekte als Blätter um Objekt bauen.
Das heißt, die primitiven Werte in Java bilden bereits die Blätter.
Also ihr könnt sozusagen, wenn ihr so euch das Objektgeflecht vorstellt,
als irgendwie so ein Geflecht von Objekten mit Beziehung zueinander,
dann hängen die Werte irgendwo so an den ganz unten, an diesem Baum.
Weil von einem Wert gibt es eigentlich keine Referenz auf ein Objekt.
Und diese Wertobjekte sollten auch keine Referenzen auf echte Objekte enthalten.
Sprachunterstützung gibt es dafür keine. Das heißt, man muss selbst beachten,
dass in einer Wettklasse die Typen aller Zustandsfelder nur Werttypen sind,
also entweder primitive Typen oder Wert lassen.
Das Dringen kann als eine Wertklasse angesehen werden,
das habe ich ja schon angedeutet,
dass fast alle Eigenschaften von Stringen dafür sorgen,
dass die sich wie ein Objekt, wie ein Werttyp verhält.
Nur bei den Referenzen ist es halt noch so ein bisschen,
da schimmert es halt noch durch.
Aber das Dringen ist tatsächlich auch Final, deklariert,
ihr könnt keinen Subtyp von Stringen definieren in Java, geht einfach nicht.
Gut, keine bestehenden Objekte verändern, also im Code,
im Quelltext einer Wertklasse sollten keine Objekte verändert werden.
Auch wieder keine Sprachunterstützung da. Ihr müsst selbst
darauf achten, dass man da nicht irgendwie was verändert
Pragmatisch kann man oft zulassen,
dass so ein Rumpf einer Methode von so einer Wettklasse
mal mit einem Stringbuffer arbeitet oder mit einem Form Meta,
weil man irgendwie vielleicht Dinge ein bisschen effizienter machen will,
aber das sind so Randbedingungen, was einfach wichtig ist,
dass an der Schnittstelle von einer Wettklasse,
da sollten nicht irgendwie Objekte als Parameter reingereicht werden,
Objekttypen.
Das wäre ziemlich komisch, weil dann lässt das darauf schließen,
dass man eigentlich in der Wertklasse irgendwie Objekte verändern will.
Gut, die Erzeugung verbergen, dass es was,
was wir eben bei dem,
bei dem Type Safe In am Pattern schon gesehen haben,
die Kontrolle,
über die überzeugt,
über die Erzeugung von Exemplaren
sollte in der Wertklasse
selbst liegen
Konstrukte kann man als Private-Dicklerin, haben wir ja gesehen,
dann können Klienten nicht mehr direkt Exemplare erzeugen.
Dann kann man aber als Ersatz entweder eine Fabrikmethode anbieten oder eben halt
solche öffentlichen Referenzen, wie das bei dem ENOM war.
Aber man kann das tatsächlich auch mit Fabrikmethoden machen, wo man dann sagt,
selektiere mir ein Datum und dann kann man darauf zugreifen.
Das ist also im Grunde genommen sowas wie hier jetzt,
dass ich da tatsächlich hier auch sowas habe wie einen Selektor.
Und das New-Datum ist eigentlich auch ein Selektor,
weil ich eigentlich logisch ein Datum selektiere, was ja schon immer da ist.
Und dafür nur ein Objekt erzeugt bekomme.
Wenn man das so macht,
wenn man tatsächlich diese Objekterzeugung kontrolliert und tatsächlich auch garantiert,
dass es zu jedem Wert nur ein Wertobjekt in Java gibt,
dann kann man sogar auf diese Regel sechs verzichten,
dann braucht man als Klient nicht jetzt immer nur mit Equals und Hashcoot vergleichen.
Also dann kann man tatsächlich sogar eine Referenzgleichheit erwähnen.
Ihr dürft tatsächlich bei dem Type-Safe-In am Pattern,
ihr dürft Elemente eines E-Numms mit Referenzgleichheit vergleichen, weil ihr garantiert ist,
dass von jedem Element des Typs nur ein Exemplar da ist.
Dann könnt ihr also auch tatsächlich den Referenzvergleich machen.
Gut, und üblicherweise sollte man schon Equals und Hashcoot implementieren.
Das ist hier auch nochmal in diesem Quelltext
zu sehen
Relativ weit unten, sorry, einmal runtergeblättert.
Nee, doch nicht. Plus, doch nicht so weit
. Muss ich wieder ganz hoch. Hier ist Equals,
so wie ihr es kennt. Also der Typ des Parameters
ist Object, muss es sein. Dann das übliche Spiel.
Ich muss erst mal prüfen, ob der Parameter überhaupt ein Datum ist,
weil sich nur mit zu einem Datum gleich sein kann.
Und wenn das der Fall ist, dann kann ich tatsächlich
hier die Typ-Zusicherung machen, also hier eine Typ-Zusicherung.
Das heißt, ich interpretiere die Referenz,
die mir da übergeben wurde vom Typ Object jetzt als ein Datum
und kann jetzt auf Tag und Monat und Jahr zugreifen und kann dann feststellen,
ob wirklich diese beiden Exemplare gleich sind
Und passend dazu dann hier, Hashcode implementiert mit so ein
bisschen Geschichten, dass es möglichst verschiedene Hashcodes sind.
So, wunderbar. Und damit haben wir eigentlich schon alles gesagt,
was man sagen kann zu Regeln, wie man in Java-Werttypen selbst programmiert.
Das kann ich jetzt noch mal kurz zusammenfassen.
Ich habe jetzt versucht darzustellen, dass Werte und Objekte was
ziemlich Verschiedenes sind, dass sie sehr unterschiedliche Eigenschaften haben.
Die haben wir versucht, hier rauszuarbeiten und haben gesagt,
naja, so zustandsbehaftete,
vergängliche Gegenstände und Konzepte lassen sich gut als Objekte modellieren
Zeitlose, unveränderliche Größenzahlen, Zeiträume werden sinnvoll als Werte dargestellt.
Fachliche Werte spielen in vielen Anwendungsbereichen eine große Rolle.
Also das ist einfach so, dass da immer wieder man,
wenn man in einen Entwendungsbereich guckt, sowas erkennen kann,
wie Kontonummern, wie Zeiträume, wie Quartale und ähnliches.
Und oft ist es eben so,
dass man da nicht einfach die Zahlen hernehmen kann,
sondern eigentlich so fachliche Operationen an diesen Typen modellieren will.
Die OO-Sprachen stellen neben den Objekten auch elementare Werte zur Verfügung.
Also Java, wie gesagt, die primitiven Typen,
aber die haben leider in Java keine einfache Möglichkeit definiert,
wie man selbst solche ähnlichen Typen wie Int oder Float
bauen kann
Das ist erstmal das, was ich jetzt hier sagen wollte.
Gibt es jetzt noch Fragen zu dem, was ich heute
hier erzählt habe? Das scheint alles einigermaßen klar zu sein.
Dann könnten wir nochmal so ein bisschen ins Storesi gehen.
Die nächste Quizfrage. Welche der folgenden Aussagen zu werten,
im Gegensatz zu Objekten, also zu Werten oder Werttypen,
ist falsch. Können wir mal gucken. Also die erste
Aussage ist, Werte sind zeitlos. Die zweite Aussage,
es gibt genau eine Repräsentation für einen Wert.
C, ein Wert kann nicht kopiert werden und D,
die primitiven Typen in Java
sind Werttypen
Welche von diesen Aussagen ist falsch? Da sehen gut aus,
wir kommen schon gut wieder über 40 Stimmen.
Ja, sehr schön. Ich glaube, das reicht dann
auch. Haben sich möglichst alle entschieden. Ja,
ich halte das mal an. Jetzt gucken wir mal erstmal
auf die Verteilung der Antworten
Da sagen also, die Aussage, dass es genau eine Repräsentation für einen Wert gibt,
dass es die Mehrheit, der Mann,
dass das das Falsche ist, also fast 50 Prozent.
32 sagen, dass die Aussage, dass ein Wert nicht
kopiert werden kann, falsch ist. Also muss man entweder aufpassen,
dass es so diese doppelte Verneinung,
und die primitiven Typen in Java sind Werttypen,
da sagen einige, das wäre falsch, immerhin 14 Prozent,
da gibt es auch noch Leute, die sagen,
nee, das ist falsch, dass wirte zeitlos sind.
Also natürlich sind Werte zeitlos,
also ist das keine falsche Aussage, die primitiven Typen,
das habe ich versucht darzustellen, Absolut, werttypartig.
Das heißt also auch hier, das heißt,
die richtige Antwort ist tatsächlich, es gibt genau eine Repräsentation,
ist, das ist eine falsche Aussage.
Ja, weil für die Zahl 42 gibt es die römische Darstellung,
die arabische Darstellung und was weiß ich wie, ganz viele Möglichkeiten.
Das ist einfach eine falsche Aussage. Und diese Aussage
ist tatsächlich nicht falsch. Das ist tatsächlich richtig,
dass ein Wert nicht kopiert werden kann.
Das hatte ich ja auch vorher eingangs erzählt. Also Werte
zu kopieren ist irgendwie eine ziemlich komische, komische Idee.
Okay, schön, schön. Mal sehen,
ob ich euch nochmal aufs Glatteis führen kann.
Ich habe noch eine
Welche der folgenden Aussagen zu Objekten ist falsch? A,
Objekte existieren in Raum und Zeit, Objekte können unveränderlich sein.
Zwei gleiche Objekte sind automatisch auch identisch, Objekte sind potenziell veränderbar.
Ich fürchte, die ist ziemlich einfach zu beantworten.
Da will ich jetzt
mindestens 70 Prozent sehen
Okay, wir haben wieder über 50 Stimmen, ja,
55, ja, ich gucke noch mal 650, ja, toll.
Ich halte das wieder an. Wir gucken mal zuerst auf die Verteilung.
Sehr schön. Ich bin stolz auf euch. Ich wollte 70 Prozent,
ihr habt mir 96 gegeben, das ist also,
da würde ich auch bei der 16.000 Euro-Frage,
würde ich da jetzt wahrscheinlich mich drauf verlassen, auf den Publikumsjoker.
Ja, das war auch, glaube ich, ziemlich leicht.
Also gar keine Frage. Das ist natürlich richtig. Objekte sind veränderbar. Klar,
Objekte existieren in Raum und Zeit habe ich deutlich gesagt,
Objekte können unfair, das habe ich auch gesagt, also klar.
Zwei identische Objekte sind automatisch gleich. Das ist richtig,
aber nicht zwei gleiche Objekte sind automatisch identisch. Gut,
das war es dann für heute, wenn da keine Fragen
mehr sind, sind wir heute mal früher fertig.
Vielen Dank