So, wir können, glaube ich, anfangen.
Ich freue mich, dass Sie alle da sind. Ich freue mich,
dass Sie ein schönes Wetter ist und dass Sie trotzdem da sind.
Wir sind heute beim Thema Fachwerte anbekommen. Wir haben beim letzten Mal,
oder die letzten paar Termine ja über Modellierung gesprochen.
Wir haben darüber gesprochen, wie wir die Konzepte so darstellen,
dass andere Entwickler, die gut verstehen, dass Entwickler,
die gut verstehen, über längere Frist hin,
dass man dort drin gut fachliche Konzepte darstellen kann.
Und natürlich,
wie wir die in Objekt und hier der Programmierung umsetzen
Heute ist der letzte Termin, der sich auch noch damit beschäftigt.
Nächste Woche, wenn wir uns mit Refactoring beschäftigen.
Heute geht es uns um Fachwerde. Wenn wir uns noch mal die Entwurfsregeln anschauen,
die wir schon ein paar Mal gesehen haben, da gibt es das Werkzeug,
das, womit der Mensch interaktiv arbeitet bei interaktiven Systemen,
der Service, der etwas ermittelt, der sozusagen eine,
wie heißt es, fachliche Dienstleistung darstellt und das Material,
das, was wir bearbeiten.
Die Fachwerte sind etwas Spezielles,
die verdienen ein bisschen spezielle Betrachtung und zwar Fachwerte
sind unveränderliche Dinge
Und das hatten wir ja schon mal in einem Beispiel,
oder schon mal besprochen, so im groben Überblick,
als ich diese ganzen vier Sachen vorgestellt habe.
Die Fachwerte sind Dinge, die man letztlich
auf etwas zurückführen kann, was wir nur verwenden.
Was wir nicht bearbeiten. Deswegen kommt hier rein unveränderlich und
die Darstellung, die Anwendung in Services, in Werkzeugen,
unterscheidet sich von der Anwendung von Materialien.
Und wir werden uns also heute mit diesen Fachwerten beschäftigen
Warum gibt es diese Werte? Ist die Gliederung für heute,
woran erkennen wir die,
wie unterstützen uns Programmiersprachen und dann ist der Übergang,
wie sieht das in Java aus und das wird dann Fred mit Java uns fortsetzen.
Letztlich modellieren ist das, worüber wir in dieser Veranstaltung am meisten sprechen,
Konzepte so darstellen, dass sie auch der Mensch versteht.
Dass sie der Computer versteht, ist keine Kunst,
das kann quasi jeder. Wir wollen sie so darzustellen,
dass sie da auch der Mensch versteht,
der Kollege versteht, der neben uns,
den wir nie sehen vielleicht,
oder der in fünf Jahren
daran arbeitet
Wir hatten ganz am Anfang der interaktiven Systeme damit begonnen,
dass wir gesagt haben, Menschen arbeiten mit Werkzeugen, arbeiten mit Materialien.
Also dieses Werkzeug ist zum Beispiel so eine Dialogmaske,
die sieht nun nicht irgendwie besonders sexy aus.
Wir bearbeiten hier Zahlenkolonnen. Das ist trotzdem,
auch wenn das ein bisschen so aussieht wie Excel,
ist es doch eine Anwendung, die für ein Unternehmen gemacht worden ist.
Also für die Abläufe, die dem Unternehmen, die dem Unternehmen wichtig war,
die das Unternehmen brauchte, was seine im Unternehmen eigene Arbeitsabläufe beschreibt.
Und was wir Was wir brauchen, ist letztlich,
oder was wir bei Modellierung unterstützen müssen,
ist nicht nur so etwas erstmalig zu entwickeln,
sondern die Konzepte, die darin abgebildet sind,
die fachlichen Konzepte, die Arbeitsprozesse in einer Form darzustellen,
dass man sie leicht ändern kann.
Wir erinnern uns, solche Arbeitsprozesse, wie man hier mit
so einem Werkzeug durchführt, die unterliegen vielen Änderungen.
Manche von diesen Quellen von Änderungen sind gesetzlicher Natur.
Wir müssen jetzt plötzlich etwas anders machen.
Ganz häufig ist das in den Steuergesetzen und in den Sozialgesetzen,
da erinnert sich quasi jedes Jahr irgendwie so gefühlt sieben Prozent
oder sowas
Es gibt auch Bereiche, da ändern sich seltener was dafür, umso mehr.
Einige von ihnen erinnern sich vielleicht an die Euro-Umstellung.
Das sah dann so aus, dass man tatsächlich in den
zwei Währungen hatte über einen Zeitraum von zwei oder mehr Jahren,
je nach Planungshorizont der Unternehmen.
Stellen Sie sich vor, eine Software, die eigentlich immer
nur einen Speicherplatz hat für eine Währung und plötzlich zwei Währungen.
Und ich muss in beiden ein- und ausgeben.
Das ist nicht nur eine Herausforderung für eine Kasse,
wenn ich dann plötzlich zweimal Wechselgeld haben muss.
Nein, das ist auch eine Herausforderung für die Umgestaltung,
solche IT-Systeme
Diese Umgestaltung ist es, die eigentlich Modellierung erforderlich macht.
Schauen wir uns das ein bisschen genauer an.
Wir ziehen uns jetzt hier mal die obere Tabelle raus.
Die ist quasi unten noch mal auf der nächsten Folge noch
ein bisschen größer dargestellt. Und das,
was wir hier in den Spalten haben, Quartalantragsdatum,
Zeitraum und ZDP, was auch immer das für ein Code ist.
Ich habe die Anwendung nicht gemacht. Ich weiß es nicht
so ganz genau. Das sind fachliche Werte. Die haben
eine Bedeutung, die haben einen Wertebereich,
die haben Gültigkeitsregeln, die werden in irgendeiner Form verarbeitet
Und die Regeln dahinter, das sind am Ende die fachlichen Regeln,
die auch ein Unternehmen zu seinem Know-how zählt. Ja,
wenn Sie sich vorstellen, zwei, vielleicht ist Ihnen das ganz gewärtig,
man bestellt was im Internet und Sie können sich sicherlich vorstellen,
wie das für so ein Webshop aussieht,
der hat sehr genaue Regeln.
Und wenn er die nicht, und seine Regeln sind vielleicht
ein bisschen besser als die von dem Mitbewerber,
deswegen kann er einen ein bisschen besseren Preis machen.
Und dann kommen die Kunden mehr zu ihm. Zum Beispiel,
wie viel Lager halt langer Menge hält man typischerweise? Ja,
das hängt man, macht man sehr abhängig davon,
von der Jahreszeit, von den Abverkäufen der letzten Woche,
von der Preisentwicklung am Markt oder so etwas.
Oder welchen Paketdienst benutze ich für welche größer
Oder welchen Kunden, mit welcher Historie erlaube ich, auf Rechnung zu kaufen?
Und welche, von welchem verlange ich Vorkasse? Weil natürlich die Leute,
die Vorkasse gezeigt kriegen als Zahlungsform, die brechen viel häufiger ab,
den Kauf als die Leute, die dann sagen können,
okay, ich zahle auf Rechnung oder auf Bankeinzug.
Also diese Wehrgeschäftsregeln sind hier hinten dran.
Wir schauen uns aber heute die Werte an.
Werte, wir haben schon gesagt, Fachwerte. Ja,
und wir können hier, wenn wir Werte anschauen,
das zum Beispiel sagen, hier haben wir Dinge,
die könnte man durchaus auch als Objekt darstellen.
Wir haben ja alle gelernt, Objektorientierung ist heute Mainstream.
Man macht heute alles, betrachtet heute alles als Objekte.
Das war ja auch so die Idee von SE1. Und alles seien Objekte.
Das können wir natürlich machen. Aber, und das,
was jetzt aber ist, steht hier in diesen Kästchen,
ja, wir können zum Beispiel einen Zeitpunkt natürlich als Objekt darstellen.
Und das Aber lautet, Objekte kann ich immer erzeugen.
Ein Zeitpunkt kann ich nicht erzeugen, der ist schon immer da.
Ich kann ihn erreichen oder überschreiten,
aber ist schon immer da
Ein Zeitraum. Ja, Objekte kann ich verändern.
Der Zeitraum ist eigentlich, der ist, wie er ist.
Ich kann ihn wählen, ich kann ihn abwählen.
Ein Geldbetrag. Das ist ein Wert. Hier steht gleich
in doppelter Hinsicht ein Wert. Also das ist auch etwas,
was ich kaum bearbeite. Ich brauche das nicht als Objekt.
Die 100 Euro, die haben keinen Zustand. Dadurch,
dass es ein Betrag ist, ist es schon der Zustand.
Die Kontonummer, das ist schon ganz klar.
Die Kontonummer, da passiert nicht viel damit.
Ich muss damit
nichts machen
Das Konto als solches hat einen Zustand,
es kann überzogen sein, es kann etwas haben,
es kann einen Freibetrag haben oder irgendwie ein Steuernummer dran kann hängen.
Ja, aber die Kontonummer selber ist eigentlich ein Wert.
Das Gleiche trifft zu auf die Sozialversicherungsnummer, die ist sogar
etwas, was mein Lebenslang mit sich unverändert trägt.
Soweit Dinge, die erst mal als Objekte in der ersten
Idee in der naiven Idee als Objekte betrachtet werden könnten.
Und wir merken jetzt, es gibt ein paar Dinge,
die sprechen dem Konzept des Objekts entsprechend dem Konzept nicht
So etwas kennen wir durchaus auch von anderen Sachen.
Wenn wir einfach mal ganz auf das zurückgehen,
womit man beim Programmieren anfängt, mit mathematischen Werten.
Intager, Float, vielleicht mit bulschen Werten auch noch.
Ja, also diese mathematischen Werte, die man in der
Programmierung hat, ganze Zahlen, rationale Zahlen, Wahrheitswerte.
Ja, sind das Objekte? Also man kann das natürlich
so betrachten und tatsächlich, wir werden dann noch Programmiersprachen erwähnen,
die tatsächlich das so machen. Die machen das ganz,
also Also Objektorientierung ist das höchste Prinzip, was diese Sprachen kennen.
Und da kann man auch die vier als Objekt betrachten.
Aber eigentlich brauche ich die vier nicht als Objekt.
Ich kann sie nicht erzeugen, die ist schon immer da.
Ich kann sie verwenden. Die Zahl Pi ist noch was Richtiges.
Oder Two and Falls. Ja, also das sind doch eher Werte.
Und tatsächlich wäre Java schön ein bisschen genauer kennt,
der weiß, das sind tatsächlich keine Objekte in Java.
Lassen Sie uns anschauen, was wir mit diesen Werten eigentlich machen.
Wir wollen ja immer wieder zurück auf Werte in der Modellierung
verwenden. Wir fangen jetzt mal mit der Mathematik an
Diese Zahlen, mit denen wir normalerweise mathematischen Operationen rechnen,
das sind Formen von Werten. Ja, wir identifizieren damit etwas,
wie eben diese Sozialversicherungsnummer, eine Steuernummer, eine Autonummer,
Kontonummer, Personalnummer steht noch hier.
Wir können damit zählen, wir können damit ordnen.
Ja, die Hausnummern sind zum Beispiel geordnet.
Ja, oder ja. Und wir können Sachen repräsentieren,
die wir irgendwie als physikalische oder sonstige Größen messen können.
Temperatur, Lichtstrahlung, Körpergröße, Masse,
was auch immer
Und diese Dinge werden mit der Algebrei berechnet, die werden numerisch verwertet.
Soweit können wir das mal soweit sagen, die Zahlen,
die wir so in der Mathematik haben, das sind auf jeden Fall Werte.
Keine Objekte, Werte, aber umgekehrt sind fachliche Werte auch Zahlen.
Und wenn wir das überlegen, wie sich das verhält,
dann sollten wir überlegen, fachliche Werte,
wir haben den Begriff Fachwert, die haben eine Bedeutung,
die haben eine Bedeutung in dem Anwendungsbereich.
Eben war so etwas mit Zahlen und Quartalen,
wenn wir jetzt mal fachliche Bedeutungen nehmen von Werten,
die wir in unserem Leben kennen, die Bankleitzahl,
jetzt IBAN oder die Postleitzahl.
Das sind Werte, mit denen wir umgehen.
Das sind Werte. Meine Adresse hat eine Postleitzahl. Und
dazu gibt es eine fachliche Bedeutung. Es gibt Operationen,
wir hatten eben Intager Real, hier die Operationen, die sind eher etwas anders.
Könnte Nummern, wir hatten eigentlich normalerweise nicht addiert,
aber höchstens, wenn ich mal in der Prüfsumme bilde,
keinesfalls subtrahiert, Geld gibt Beträge, klar, Adrian Subtrahirn,
aber miteinander multiplizieren tun wir das eigentlich nicht.
Ja, wir haben, wenn wir zwei Kilo Erdbeeren kaufen,
dann kostet es das zweimal so viel wie ein Kilo Erdbeeren,
ja, aber wir rechnen nicht ein Kilo Erdbeeren,
mal dem heutigen Datum oder mal der Miete oder irgendwas anderes.
Das eigentlich nicht
Dann gibt es viele fachliche Werte, die sich nicht durch
Zahlen ausdrücken lassen. Ja, wir haben hier Beispiele,
Grundfarben, Rot-Grün-Blau oder die Monate eines Jahres.
Wir wissen schon, in Java sind das Aufzählungstypen.
Und diese Dinge sollten wir in Programmen unterscheiden von Objekten.
Denn wenn wir einfach nur sagen, Zahlen, natürlich,
wenn das eine Zahl ist,
dann kann ich damit auch rechnen mit einem Geldbetrag,
ist die Rechnung sehr eingeschränkt.
Nächste Folie, Gegenüberstellung, was ist jetzt nun ein Wert
und was ist ein Objekt?
Wir haben eben gesehen, dass es was unterschiedliches ist
Was ist denn nun das Zentrale bei Wert? Was ist
bei Objekt? Das sind, wenn wir das verstanden haben,
das ist eigentlich so der Schlüssel zur heutigen Lehrveranstaltung,
wenn Ihnen das klar ist,
können Sie auch ganz leicht da eine Klausurfrage beantworten.
Ist das ein Wert? Ist das ein Objekt? Lassen
Sie uns mit dem Wert beginnen. Werte sind immer irgendwie
immateriell, also nicht in einem Material gebunden, abstrakt.
Ja, die Zahl 2 haben wir hier zwei Früchte,
zwei Stäbchen, die Ziffer oder wie auch immer.
Abstraktion häufig von etwas häufig auch zur Identifikation,
hatten wir
schon gesagt
Ein Objekt hatten wir eben schon, ist, ich kann
ein Objekt erzeugen, es ist nämlich eine neue Instanz einer Klasse.
Ich kann Objekte zerstören, ich kann sie auflösen.
Und wenn ich sie erzeugen und auflösen kann,
dann haben sie natürlich einen Anfang und ein Ende.
Also dann haben sie eine Lebensdauer. Und diese Lebensdauer können wir kurz uns überlegen,
also wenn wir das Objekt B betrachten,
dann gibt es einen Anfang und ein Ende und dazwischen so einen Zeitraum.
Das ist die Zeitachse und das ist dann die Lebensdauer. Und da gibt es diese Zeit,
drei Zeitabschnitte, man könnte sagen,
bevor das Objekt erzeugt wird, also es existiert noch nicht,
dann gibt es die Das ist jetzt also vor der Erzeugung,
dann gibt es die eigentliche Lebensdauer und wenn ich es aufgelöst habe,
da war es früher mal da, jetzt ist es nicht mehr da, das ist nach der Zerstörung.
Und da gibt es Objekte, die haben früher gelebt oder existiert oder
ein Objekt wird später erzeugt und das existiert dann entsprechend später.
Soweit zu Objekten, die haben eine Lebensdauer,
die haben einen Zeitraum, beim Wert ist das zeitlos.
Also 42 wissen sie alle, das ist ein ganz besonderer Wert,
aber Zeit und Dauer kann ich bei einem Wert
eigentlich nicht verwenden
Die entstehen nicht, die werden nicht verbraucht.
Während ein Objekt, das wird schon irgendwie verbraucht. Ja,
also wenn ich so eine nette amerikanische Kiste habe,
ja, kann es durchaus sein,
dass die irgendwann nicht mehr so schön ist,
bis das der TÜV uns scheitert.
Und es gibt also wirklich eine Identität und es gibt auch ein Leben, eine Veränderung.
Ja, und diese mag, das sind erkennbare Merkmale,
das ist, wir sprechen auch vom Zustand eines Objekts.
Während der Wert, da ändert sich nichts mehr. Ja,
42, bleibt 42, man kann das auf irgendetwas beziehen,
man kann es berechnen, man kann Funktionen damit machen.
Ja, aber ich kann hier nichts
groß verändern
Das Gleiche trifft zu auf den Zustand. Ein Objekt hat einen Zustand,
leer, voll, mein Einkaufswagen könnte leer sein und voll sein.
Und wenn ich das Objekt verändere, verändere ich den Zustand
und das passiert irgendwie mit Aktionen, Ereignissen über die Zeit.
Gut, kleine Anmerkungen, es gibt auch unveränderliche Objekte,
aber bei den meisten ist das doch so,
dass ich sie verändere, während Werte zustandslos sind.
Werte haben keine besonderen Lebensdauer, hatten wir schon gesagt,
und sie verändern sich nicht.
Also die Zahlen, die Zahl Pi und so weiter
Ein weiterer Unterschied betrifft den Vergleich. Und das ist,
also so wie wir uns langsam der Sache ernähren,
wie sie denn das in einer Programmiersprache aus,
wie sieht das denn bei unserem Fachwerten aus.
Wenn wir also zwei Bücher haben,
dann sind das nicht unbedingt identische Objekte. Klar,
das kann beides, das Buch über UML 2 klar,
äh zwei Glas klar sein, das UML-Buch,
was wir vielleicht verwenden,
ja,
und unser Kollege hat
auch so ein Buch
Das sieht äußerlich ganz gleich aus. Trotzdem ist es nicht
gleich. In meinem Buch gibt es ein paar Eselsohren,
ich habe mir ein bisschen was reingeschrieben.
Das ist in seinem Buch nicht. Und wenn ich schlau bin und
so viele Leute in meinem Jahrgang haben so ein Buch,
dann sollte ich vielleicht auch meinen Namen reinschreiben, um diese Identität zu kennzeichnen.
Also wir können damit unterscheiden, gleich oder identisch.
Im Deutschen das Gleiche und dasselbe, vielleicht haben sie jemanden in ihrem Bekanntenkreis,
da hat dann immer die Leute korrigiert,
ist das nun dasselbe oder das Gleiche?
Also hier geht es um Gleichheit und Identität.
Gleichheit auf die Merkmale, die so ein Ding hat und
Identität auf die Zusammenhänge,
die ein Objekt hat
Ja. So, soweit zusammengefasst. Wir haben Werte,
die sind in irgendeiner Form abstrakt, zeitlos, unveränderlich.
Das Objekt hat einen Zustand, damit könnte man es verändern.
Und es kann erzeugt werden, es kann zerstört werden,
das heißt, es hat eine Lebensdauer, es hat eine Zeit.
Soweit. Zusammengefasst, Werte, Objekte sollten wir als zwei Konzepte betrachten.
Objekte hatten wir schon länger besprochen und werde ist jetzt das,
was wir heute, wo wir uns heute drauf fokussieren.
Und wenn wir die verstehen, können wir bessere Software bauen,
weil wir die Sachen ja unterschiedlich behandeln wollen.
Wir hatten schon gesagt, es gibt nicht alle Operationen bei
einem Wert. Und jetzt ist die Frage,
wie unterstützt denn so eine Programmiersprache diese Werte, diese Objekte?
Ganz besonders, wir gucken uns in Objekte und hier die
Programmiersprachen, wie sieht es damit aus?
Ja, Objekte und hier der Programmiersprachen haben erstmal als Konstrukt Objekte.
Das ist das, was sie... Deswegen heißen sie objektorientiert,
klar, nicht besonders überraschend. Und zwar basiert das auf
der Klasse. Die Klasse kann Instanzen erzeugen, Exemplare.
Und das sind Objekte, bestimmter Typen. Die Klasse ist
sozusagen das Baumostor für die Objekte. Das Baumoster gibt vor,
was dort alles möglich ist, nämlich der Typ,
das Schlüsselwort Klaas, ist es in Java und CePlus Plus und CeShap,
was hier diesen Typ konstruiert.
Und deswegen heißt das Ding
auch Typkonstruktur
Werte gibt es innerhalb der Sprache auch. Wir hatten schon gesagt,
in Java sind diese elementaren Typen eigentlich Werte, Integer,
Bite und Shorts sind alles ganz zahlige Werte,
Long ist auch ein ganz zahliger Wert,
Float und Double sind Kleidkommerzahlen, Bulien kennen sie alle,
der Wahrheitswert und Charakter ist ein Wert für ein Zeichen,
nur ein Zeichen, hat deswegen auch eine abzählbare Menge von Elementen.
So, wenn die so schön nützlich sind, Diese Werte,
wie ich eben gesagt habe, warum gibt es denn nicht mehr?
Warum gibt es nur diese Paare für Zahlen? Und Mathematik
ist ja nun mal nicht das wichtigste Anwendungsfeld von Software.
Eigentlich wollte man ja wahrscheinlich, da müssten wir jetzt die
Erfinder dieser Programmiersprachen fragen, warum die das gemacht haben.
Vielleicht wollten sie wirklich das ganz pur haben, Purismus.
Und tatsächlich gibt es solche Sprachen. Ich hatte das schon dargestellt,
dass es solche Sprachen gibt, zum Beispiel Smalltalk.
Das ist die Sprache, die von Konzepten her Java
am meisten Party gestanden hat.
Die hat wirklich tatsächlich auch Inteacher als Objekt
Halt immer, dass bis auf die Atmetik runtergebrochen,
dort ist es so, wenn sie eine Zahl eins haben,
als ganze Zahl, dann wird sie erzeugt als Objekt.
Und wenn sie die eins mit der drei addieren,
dann sagen sie, schicken sie die einzelne Nachricht,
addiere dich mit der drei.
Und dann addiert die sich mit der drei und heraus
kommt ein neues Objekt, das ist dann die vier.
Ja, also tatsächlich ist das dort, sind das tatsächlich Objekte.
Wobei das nicht ganz ungefährlich ist und nicht ganz,
weil wir müssen dann ganz genau aufpassen,
wenn wir vergleichen,
sind dann das doch
die gleichen Dinge
Die Programmiersprache Eifel, vielleicht hat der eine oder andere von Ihnen das gehört, von einem Menschen,
der ganz viele Forscher oder ganz viele Programmiersprachen entwickelt hat, Betrong Me,
eine Sprache, die Vor- und Nachbedingungen im Laufzeitsystem hat.
Da gibt es zur Laufzeit, sind das alles nur Objekte und self,
das sind auch, ist etwas, was man nicht so breit verbreitet ist, gibt es nur Objekte.
Okay, es gibt ein ganzes Spektrum von Dingen,
zum einen können wir sagen,
auf der einen Ende der Skala nur Werte,
am anderen endet der Skala nur Objekte und wenn man dann die Zeitachse betrachtet,
Da gibt es Sprachen, die weit weg davon sind.
Also wir hatten schon gesagt, hier dieses Self,
was ein bisschen Exuit heute ist, Smalltalk,
was heute in der Leitung nur noch ganz wenig in Verwendung ist,
war meine persönliche erste Programmiersprache, objektorientierte Programmiersprache.
Java, dass wir hier verwenden, Sie schaben es deutlich später entstanden.
Und es gibt noch Sprachen, die dann eigentlich nur Werte
haben, wie die funktionalen Programmiersprachen zum Beispiel. Ja,
wenn wir alles nur, wir können ja natürlich jetzt sagen,
so wie wir das eben gesagt haben, puristisch,
wenn es alles einheitlich ist, alles sind nur Objekte,
super, können wir doch,
ist doch könnt ihr doch die Welt ganz toll sein.
Die Welt könne doch
einfach sein
Wir haben ein einfaches Modell, es gibt nicht so viele Elemente in der Sprache.
Ich brauche nur zu sagen, okay, kreiere mir ein
neues Objekt von der Klasse, das kennen wir alle.
Und ich kann ganz einfach sagen, wie gehe ich mit einer Variablen um?
Ich erzeuge die, ich kann auf sie zugreifen mit einer Referenz und so weiter.
Ich kann sie ganz einfach verallgemeinern, wunderbar. Der sprach,
Designer freut sich darüber, weil er eine einfache Sprache hat,
weil er einen einfachen Compiler bauen kann.
Aber wenn wir jetzt in dem Fachlichen alles,
was die Welt so bietet, Objekte mal zu Objekten machen müssten,
wie eben zum Beispiel unsere Kontonummer, Versicherungsnummer, die Postleitzahl,
dann wird das schon ein bisschen schwierig und dann ist das irgendwie,
hat das was mit Verbiegen zu tun.
Ja, also sie kennen ja alle diesen Polizistenwitz,
wo die Polizisten das runde und eckige Teile sortieren mussten und
zehn Prozent der Leute haben es mit Intelligenz gelöst und mit
ganz viel Intelligenz gelöst und 90 Prozent mit ganz viel Kraft.
Das ist also, es passt dann manchmal nicht so richtig.
Und wir wollen jetzt deswegen das getrennt halten. Das ist
das Anliegen der Fachwerte. Deswegen schauen wir uns zunächst erstmal an,
die Objekte, zu denen gehören Typen,
Und von diesen Typen wollen wir dann zu den Werten kommen.
Ja, in der Objekte und hier um Programmierung haben wir Objekte,
die sind durch Klassen definiert, das Klasse,
die Klasse ist das Baumuster und damit der Typ.
Ja, jede Klasse definiert den Typ und wenn wir nur Zahlen betrachten,
dann ist das auch die Operation,
die Wertemenge und den Wertebereich der und die Operationen der Zahlen,
aber auch für alle anderen Instanzen trifft das zu.
Der Typ enthält auch Operationen. Und die Exemplare hat dann
sozusagen die Elementmenge dieses Typs. Und ja,
damit haben wir eigentlich gesagt,
Objekte basieren auf Typen
Und wie ist das jetzt mit den Werten? Auch diese
Werte haben letztlich einen Wertebereich und damit basiert das auf Typen.
In Java war das für Indon Bullyen zum Beispiel und die Menge dieser Typen ist nicht veränderlich,
also wer erzeugen da nichts Neues, wer erzeugen,
das ist immer gleich bei Intager, ist das begrenzt,
wenn Sie jetzt sagen, es sind ja unendlich viele ganze Zahlen,
Prinzip haben Sie recht,
aber praktisch ist das immer begrenzt durch die Menge der Bits,
die ich dafür spendiere.
Bei Intager ist das 2.32 Uhr,
bei Long ist das sehr viel mehr.
Und Bullyen hat eben
genau zwei Elemente
So, wir haben also eine Elementmenge, die ist unveränderlich und deswegen haben wir eigentlich auch hier nicht keinen Konstruktor. So,
etwas, was wir vorhin schon mal gesehen hatten,
Objekt und Typ nebeneinander, Objekte und Wert und Typ,
der Wert, abstrakt zeitlos, unveränderlich,
das Objekt mit Zustand erzeugbar und veränderbar,
aber jetzt kommt noch hinzu, wir haben Typen,
das Wert, der Wert kann über einen Werttyp definiert sein,
wo die Operationen drinstecken und die als Selektoren und die Wertemenge,
die unfallländerlich ist.
Bei Objekten ist es so, wir haben eine dynamische Wertemenge,
wir können immer neue Objekte erzeugen, so viele,
bis unser Speicherplatz nicht mehr ausreicht.
Und dieses Erzeugen passiert mit Konstrukturen,
das haben wir hier drüben nicht, wir erzeugen hier nichts.
Aber die beiden Sachen haben was gemeinsam, das ist das,
was wir eben mit dem Typ hatten.
Der Typ fasst zusammen, die Menge der Elemente und die Menge der Operationen.
Und wir verwenden die dann als Variablen dieses Typs.
Soweit Ob zu der Unterscheidung zwischen Wert und Objekt,
wo brauchen wir das praktisch?
Praktisch brauchen wir es immer dann, wenn wir damit arbeiten.
Wenn wir damit arbeiten, müssen wir häufig stellen,
feststellen, ist etwas gleich, größer, kleiner.
Aber am meisten ist die Frage der Gleichheit. So,
und da wiederum gibt es wirklich tatsächlich Unterstützung durch die Programmiersprache für beide Konzepte.
Für den Wert und für das Objekt.
Lassen wir uns zunächst erstmal bei Java anfangen.
Wir kennen alle den Ausdruck, mit dem Doppelten ist gleich.
A, ist gleich, ist gleich B.
Was bedeutet das
Was passiert bei A ist gleich B? Da werden die,
wird etwas verglichen miteinander. Was ist denn das Resultat?
Ein Wahrheitswert ist das Resultat. Ja, ich bekomme etwas zurück.
Es ist eine Operation, die etwas vergleicht und ich vergleiche hier
zwei Objekte miteinander. Aber es gibt noch unterschiedliche Sachen.
Also wenn wir hier so ein kleines Programm machen,
ja, wer weiß, machen wir eine Zuweisung,
aber das Gleiche wie zum Gleichen zugewiesen wie B, ja,
dann mache ich einen Vergleich und dann kriegen beide den gleichen Wert.
Und hier ist die Frage, wann gehe ich hier hören,
wann gehe ich hierher? Also ist das hier und das hier
etwas Unterschiedliches? Sollte das jedes Mal das Gleiche sein?
Also hier würden wir uns, hier ist klar,
vorher habe ich eine Zuweisung, dass beides ist gleich.
Hier habe ich beides mit dem gleichen Wert belegt.
Ist es dann auch gleich? Eigentlich würden wir uns doch
wünschen, dass es hier unten auch gleich behandelt wird.
Ist aber nicht so. Das heißt, wir müssen das
irgendwie unterschiedlich behandeln
Wie sieht das aus mit String? Ja, wenn ich beim String,
ist klar, es gibt Blower Case und ABBA Case,
also ich kann zum Beispiel hier das große E entfernen oder umwandeln in ein kleines E,
in dem ich hier eine Operation to lower Case damit ausführe,
dann verändere ich den ins Trinken.
Wie sieht das bei Objekten aus? Erstmal technisch, wir haben
drei unterschiedliche Formen von Gleichheit. Zunächst haben wir die Identität,
das ist das, was wir in dem kleinen Java,
in den paar Zeilen Java eben als erstes hatten,
ja,
also das eine und das andere A und B zeigt auf
das gleiche Objekt und das wiederum zeigt auf ein anderes Objekt,
hat also eine Referenz hier und diese beiden
sind identisch
Diese beiden sind nicht identisch, C und Dese,
nicht identisch, weil sie zeigen auf unterschiedliche Objekte,
auch wenn diese Objekte intern den gleichen Wert haben und auch diese Referenz,
auf die sie hier drin haben,
die zeigt auch auf den gleichen Wert.
Das heißt, hier ist es schon eine andere Gleichheit,
aber es ist auch noch etwas gleich, heißt Shallow Equality.
So, und dann gibt es noch die Möglichkeit,
dass man tatsächlich noch mehr gleich hat hat unten drin,
also die Referenz, auch wo ich drauf zeige,
das ist nicht mehr identisch,
aber es ist trotzdem der gleiche Wert,
das wäre in der Tiefe
Ist es gleich. Deep Equality. Drei unterschiedliche Konzepte von Gleichheit.
Wie können wir die unterscheiden? Und zwar können wir zunächst erst mal sagen,
das eine enthält das andere und das enthält wiederum das andere.
Ja, also das impliziert,
dass unten drunter das auch gleich ist und das impleduziert,
dass unten drunter der gleiche Wert ist.
Wenn wir über nachdenken, was sind das für Elemente,
diese Elipsen hier, das sind Container.
Das sind Objekte. Ja,
also jedes dieser Dinge ist ein Objekt,
hat eine Identität
Sehen wir es ganz deutlich. Sie sind zwei unterschiedliche Dinge und
zwei unterschiedliche Objekte, auch wenn die auf das gleiche Element zeigen.
Hier unten sind auch die 42, zwei unterschiedliche Objekte,
weil ich könnte sie zu einer anderen Zeit erzeugen,
zerstören, es sind Objekte.
Mag jemand von Ihnen kommen, der sagt,
damit den Begriff Semantik operiert, Semantik im Sinne von Bedeutung.
Wenn wir nochmal das Buchbeispiel nehmen,
ein Buch hat typischerweise solche Eigenschaften wie Titel, Auto,
ISBN, vielleicht noch eine Referenznummer und wir Wir können immer sagen,
in der Bibliothek, das Buch ist das Gleiche.
Ja, also ich hole mir das UML-Zweikler, klar,
als UML-Buch aus der Bibliothek. Und wenn ich nicht das Gleiche kriege,
was ich letzte Woche hatte, weil ich muss das zurückgeben,
dann ist das nicht so schlimm, weil es steht ja hoffentlich das Gleiche drin.
Vielleicht nicht Ihre persönlichen Anmerkungen, sollte man beim Bibliotheksbuch
ja sowieso nicht machen. Die können wir gleich ansehen,
wenn die ersten Werte gleich sind und die Referenznummer,
also diese Identifier vielleicht nicht gleich ist.
Weil der Inhalt, die Bedeutung uns gleich ist.
Aber wir können das auch selbst definieren oder anders machen.
In Java gibt es dafür ein Befehl, eine Operation,
die Operation Equels. Equels ist, wo definiert,
wer kennt, Equel kann sagen, wo steht,
wo müsste ich nach der Equels-Methode suchen, wo sie ursprünglich implementiert.
Ich kann die Erben ja, wer weiß von ihnen,
wo die implementiert ist. Die ist ja der klasse Object, implementiert.
Alle Klassen erben etwas, egal welche Klasse sie machen,
die erben alle von Object in Java und eine der vier Methoden,
die alle Klassen von Object erben,
ist Equels
Und Equals kann ich natürlich, wenn ich bei Vererbung,
wissen wir alle, ich kann Sachen überschreiben.
Ich kann also für meine Objekt,
was ich meine Klasse, die ich gerade habe,
kann ich definieren, was wird denn als Gleichheit betrachtet?
Wie wirkt denn Gleichheit? Und das könnte ich zum Beispiel sagen,
ja, das ist Aufruf einer Operation, die asymmetrisch ist.
Ich kann sie mit null vergleichen und ich kann ein paar Meter übergeben.
Und damit kriegen wir schon mit,
wie können wir das in einer Programmiersprache machen,
wenn wir das steuern können, was Gleichheit ist,
dann können wir Programmiersprachelemente nehmen,
bei denen,
die wir als Werte behandeln und welche,
die wir als Objekte behandeln
Wir hatten das Obere alles schon mehrfach besprochen.
Was ist der Unterschied zwischen Wert eurem Objekt?
Und bei Objekten müssen wir Gleichheit und Identität unterscheiden.
Das ist bei Werten nicht der Fall. So,
das heißt, jetzt wird es spannend,
jetzt wird es knifflig und jetzt kommt der Punkt,
wo sie die Falle vermuten dürfen.
Klar ist es ganz viel, ganz häufig sinnvoll, unveränderliche Objekte zu definieren.
Diese unverländerlichen Objekte brauchen wir in fachlichen Kontexten. Ja,
wir hatten jetzt zum Beispiel in einer Filmdatenbank,
wir haben ja so ein bisschen sowas ähnliches,
diese Mediathek haben wir als Beispiel immer,
da habe ich enttitelt,
da habe ich einen Regisseur und Filmlänge,
das ist unveränderlich
Das wird durch die Klasse sozusagen definiert und es hat auch nicht Zweck,
da schreibende Operationen anzubieten, lesende Operationen reichen völlig aus.
Aber es könnte natürlich sein,
dass so ein Film trotzdem als Objekt behandelt wird,
der ganze Film, weil er hat einen Zustand,
er ist gerade bis zu einer so einer Stelle abgespielt worden,
er ist irgendwo verfügbar,
vielleicht ist er beschädigt oder hat schon so eine Lebensdauer hinter sich.
Bei dem guten alten Celeloid-Film sollte man das zum Beispiel machen.
Wenn wir also für ein Objekt,
wenn wir mal bei dem Beispiel hier bleiben,
wenn wir nur unveränderliche Werte haben, nur lesende Operationen machen,
Dann ist dieses Objekt doch eigentlich ein Wert, oder?
Und diese Unterscheidung können wir ja vielleicht jetzt versuchen zu nehmen.
Aber nein, wir haben noch die anderen Eigenschaften, die auch noch zutreffen.
Wir hatten das auf der voragenden Folie, wo war es?
Ich bin jetzt, ach ne, das war bin zu weit,
bin vorwärts gegangen, hier rückwärts, genau.
Der Wert musste auch zeitlos sein, müsste auch unveränderlich sein.
Ja, es reicht nicht nur, dass Erzeugen zerstören hier wegmachen. So,
und tatsächlich können wir uns vorstellen, es ist auch Programmiersprachen,
dass man in Programmiersprache schafft, die diese Werttypen auch enthält,
wo es richtig ein Sprachkonstrukt ist und ich sage nicht,
das ist ein Objekt, ich definiere es über eine Klasse,
nein, ich habe richtig das Konzept wert mit Operationen,
die dazugehören, die nur Selektoren bieten,
die nur diesen sondierenden Zugriff haben.
Die Wertemenge ist festgelegt, ja,
die sind unveränderlich und der Compiler müsste das überwachen.
Und ich habe dann eigentlich keine Operation, die irgendetwas verändern.
Bei Programmiersprachen spricht man dann von Seiteneffekten.
Das sind keine irgendwie Dreckeffekte, sondern das ist einfach nur
, ich kann nichts anderes beeinflussen
Und ich kann die natürlich nicht definieren auf der Basis von Objekten,
weil die wären veränderlich, sondern nur auf der Basis von anderen Werttypen.
So, und deswegen lassen Sie uns so ziemlich
zum Übergang zur Programmiersprache kommen, zum Übergang zu Java.
Wie können wir in Java jetzt diese Fachwerte,
die wir für die Modellierung brauchen,
die wir für unveränderliche Dinge brauchen, wie können wir die darstellen?
Zum einen müssen wir dafür sorgen, dass sich diese Dinge nicht
erzeugen kann. Also sie dürfen keinen veränderlichen Zustand haben,
Diese Klassen, sie dürfen sich nicht auf Objekte beziehen,
weil sie sind selber nur Werte.
Und ich darf das nicht verändern. Jedenfalls nicht, wenn
ich einmal Objekt erzeugt habe. Und diese Erzeugung wollen wir
irgendwie verbieten. Wir können sie meistens nicht ganz verbieten.
Wir können sie wenigstens irgendwie unmöglich machen.
Und wir brauchen eine entsprechende Operation für die Gleichheit.
Das ist Equals. Wir brauchen zusätzlich noch die Funktion Hashcode,
die dann den Vergleich intern realisiert.
Hashcode ist auch eine von diesen vier Methoden,
die jede Klasse von Object erbt
So, und wenn wir diese Wertklassen benutzen, das ist,
wenn wir sie uns ausdenken, und das ist,
wenn wir sie dann anwenden als Programmierer in unserem Programm,
dann sollten wir immer Equals verwenden.
Immer diese Methode für Gleichheit, die durch den Schaffer einer
solchen Wertklasse definiert ist. Und eben nicht mehr dieses Gleichheits-,
den Gleichnetzoperator für Objekte, weil wir wollen ja Werte haben.
So, lassen Sie uns jetzt mal diese Eigenschaften von,
ob von Werten durchdeklinieren. Zuerst wollen wir erreichen,
die Dinge sind unveränderlich vom Zustand her.
Also es gibt nicht ein bisschen oder ganz,
sondern es gibt den Wert oder es gibt die nicht.
Wertobjekte sollten unveränderlich sein
Wie kriegen wir das in der Sprache hin? Tatsächlich hat Java dafür etwas,
Java hat die Möglichkeit, etwas durch Final zu definieren.
Ja, unveränderlich, das wird beim Kombinieren dann gleich schön abgelegt.
Und das kann ich dann ganz gut machen, dass sie wirklich unveränderlich sind.
Und damit kann ich die ganze Wertklasse auch festgelegen,
sodass es keine Unterklassen geben wird. Und auf diese Weise
kann ich auch nicht bei der Unterklasse wieder Objekteigenschaften hinzufügen.
Okay, diese Wertobjekte sollen in einer Hierarchie eingeordnet sein
und sollten keine Referenzen, ob ihr echte Objekte zulassen.
Hier steht schon Sprachunterstützung, keine. Das ist leider ganz häufig so,
dass Dinge durch eine Programmiersprache nicht unterstützt werden,
sondern dann müssen wir irgendwie hier das durch Disziplin ersetzen.
Das ist etwas, was wir uns immer wünschen.
Wir wünschen uns immer, die Tools möchten das und
das dafür sorgen, dass man es einhalten muss.
Leider geht das in diesem Konzept für dieses Konzept
gerade nicht.
Ihre Frage
Wir kommen noch auf das innere Mustern.
Die Innomerationstypen sind natürlich irgendwie auf diesen Werten basierend.
Aber wir können das nicht insgesamt als Konzept.
Sie haben recht, es wäre so ein bisschen Sprachunterstützung dafür,
weil die Aufzählungstypen uns genau das eigentlich liefern.
Sie liesten aber eigentlich Abwandlungen von diesen einfachen Werttypen wie Intetcher
oder sowas, wird ja eigentlich immer auf Intetcher abgebildet.
Aber prinzipiell haben sie schon recht,
nur wir können damit leider auch nicht so flexibel agieren,
wie wir das mit Werten gerne möchten.
Und wenn wir noch mehr Operationen brauchen oder gerade Schachtelungen,
dann reicht das, ändern wir uns nicht aus,
dann müssten wir Objekte nehmen mit dem Nachteil,
wir haben keine Sprachunterstützung,
dass man davor nicht wieder mit Objekten
Verbindungen herbestellt
Referenzen herstellt. So, das dritte, die dritte Eigenschaft war
, sollte unveränderlich sein. Was machen wir denn damit?
Ein Wert sollte nicht verändert werden oder sollte sie nicht
veränderlich sein und jetzt ist das Mikro zu Ende,
doch, jetzt geht es wieder.
Und auch ein Wert sollte keine echten Objekte verändern.
Auch hier ist es so, dafür gibt es keine Möglichkeit,
das durch die Sprache zu unterstützen.
Wir müssen selbst durch Disziplin das machen. Ja,
also in einer Wertklasse sollten wir keine Objekte verändern,
die bereits bestehen beim Initialisieren kam,
ist noch was anderes,
das kann man erlauben
Und deswegen sollte die Schnittstelle, darauf können wir nun achten.
Keine Objekttypen als Parameter zulassen. Sie kennen sowas mit String
Buffer oder Formatta, da kann ich das machen,
da wird das ja so gemacht, dass ich etwas Neues erzeuge.
Das kann man zulassen, damit das gut funktioniert, aber ansonsten eigentlich nicht.
Die vierte Eigenschaft war die mit dem Erzeugen und Zerstören.
Nun ist es so, wenn wir tatsächlich in einer objektorientierten
Programmiersprache etwas benutzen, dann ist das Erzeugen irgendwie eingebaut.
Was können wir damit machen? Wir sollten eigentlich das Erzeugen verbieten,
das heißt, die Wertklasse selber sollte dafür sorgen,
dass etwas nicht erzeugt werden kann,
weil die Menge sollte die Menge der Elemente,
es soll ja fest sein, die Wertemenge, die Elementmenge.
So, und tatsächlich gibt es dafür etwas Unterstützung dafür,
wir können den Konstruktor als Preive deklarieren,
dann kann ich den Konstruktor nicht mehr aufrufen und damit kann ich diese Erzeugung verhindern.
Stattdessen kann ich mit Fabrikmethoden etwas erzeugen oder diese Erzeugung so stören,
dass eine bestimmte Menge erhalten bleibt, Fabrikmethode war etwas,
was ein Entwurfsmuster ist,
wo es darum geht,
dass New durch etwas anderes
zu ersetzen
Wer von ihnen kennt, Fabrikmethoden noch nicht, noch nie etwas von Fabrikmethoden gehört,
2, 3. Also wenn wir Fabrik, es gibt auch ein Design-Pattern,
das heißt dann mal Factory, hat damit zu tun,
dass sich Objekterzeugung im Verbund steuere. Wenn Sie ein einzelnes Modell,
ein Objekt erzeuge, dann mache ich das mit New,
initialisiere die bei Dune New, initialisiere ich die Variablen zum Beispiel,
da ist eine Referenz auf ein RA und da muss ich das RA noch mit haben,
das kann ich machen, solange das interne Elemente sind,
also die bei Attributen liegen, kann ich das mit dem New machen,
wenn ich einen ganzen Verbund habe, zum Beispiel eine neue Buchausleihe,
muss immer verbunden sein mit einem Buch und einem Kunden.
Dann muss ich immer, dann möchte ich diese Erzeugung im Verbund
machen und das mache ich dann nicht, indem ich sage,
der ruft den auf, das war viel zu kompliziert.
Ich erzeuge dafür so ein Factory-Konzept und dieses Factory-Konzept sorgt dafür,
dass ich mich nicht darum kümmern muss,
wie geht das mit dem Erzeugen. Und dieses Konzept,
diese Fabrikmethoden, können wir dann verwenden hier,
um das Erzeugen so zu steuern,
dass die Menge der Elementtypen der Menge der Elemente in einer Wertmenge immer gleich ist.
So, Und was wir dazu tun können,
ist diese Methode Equels, nämlich diese selbst definierte Vergleichsmethode implementieren.
Die Equels-Methode kann ich durch die Gleichheit, dadurch gängige Gleichheit ermitteln.
Die Sprache kontrolliert das nicht. Wenn Sie jetzt sagen,
wieso Unterstützung steht ja keiner? Equels ist doch etwas in
der Programmiersprache. Ja, aber die Programmiersprache Java unterstützt nicht,
wenn ich hier einen Fehler mache.
Die Sucht findet das nicht. Ich kann bei Equels
alles selbst definieren
So, damit kommen wir zum Schluss des Vorlesungsteils. Wir haben zum Schluss den Schwenk zu Java gemacht,
bevor Fred uns zeigt, wie das in Java aussieht.
Können wir nochmal zusammenfassen. Wir haben besprochen, Werte und Objekte sind etwas, was wir voneinander trennen müssen. Weil das eine unveränderlich ist und das andere veränderlich,
nämlich Objekte kann ganz gut genutzt werden, um etwas mit Zustand,
etwas mit einer Lebensdauer verbundenes darzustellen und etwas,
was zeitlich zeitlos ist oder unveränderlich zahlen Zeiträume Werte und die fachlichen Werte sind dann die Sachen,
die wir in Anwendungsbereichen brauchen,
holen es uns nicht mehr reicht,
dass wir nur Intager und Bullion haben und dafür brauchen wir dann die Fachwerte,
die wir dann abbilden können in einer objektorientierten Programmiersprache,
mittels ein paar Sachen zur Sprachunterstützung und der restlichen Sachen müssen wir selbst durch Disziplin machen.
Damit am Ende der Vorlesung, vielen Dank und
ich übergebe gerne an Fred
Untertitel der Amara.org-Community Untertitel der Amara.org-Community So,
ich kann das ja einfach hier auf den Tisch legen,
dann nervt es nicht so in der Hose.
Gut, dann schaue ich doch mal, was ich vorbereitet habe für euch.
Genau. Ich wollte einfach mal nochmal so ein paar Mini-Java-Grundlagen
mit euch wiederholen. In so einem schönen, interaktiven Environment.
Ach, ihr seht doch, man sieht alles. Genau,
also es wird ja in der nächsten Java-Version,
gibt es ein tolles Tool, das heißt Jay Shell,
das ist so ein bisschen wie diese Direkteingabe in Blue Jay,
nur dass da auch ein paar mehr Dinge gehen
Ja, ich will eigentlich nur eine Shell starten, da haben wir sie.
Also, ich will einfach mal eine Variable definieren,
ich nenne die mal A und weiß ihr, den wird eins zu.
Ja, das erschreckt euch hoffentlich nicht.
Genau. Und wenn ich jetzt zum Beispiel Java bitte auszurechnen,
was ist denn A plus 2, was kommt dann da raus?
Was ist das Ergebnis von A plus 2?
Einfach mal in den Raum rufen vielleicht. Drei, genau
, schauen wir mal. Tatsächlich. Und wenn ich jetzt
frage, welchen Wettteil A, was kommt dann raus?
Eins. Sehr schön. Wir haben also hier eine Operation,
die zwei Zahlen nimmt, eins und zwei.
Und daraus die drei macht, aber weder die eins noch die zwei irgendwie verändert.
Ja. Okay, das ist hoffentlich nicht erstaunlich.
Das kann man auch mit Strings machen.
Also wenn ich zum Beispiel sage, ich habe ein String,
sagen wir mal Hello, da haben wir ihn.
Und wenn ich sage, was kommt denn raus,
wenn ich S plus World ausrechne? Das frage ich jetzt nicht,
das ist euch hoffentlich klar, dass da Hello World rauskommt.
Und wenn ich jetzt frage, was ist denn der Wert
von S? Was ist jetzt der Wert von S?
Irgendjemand eine Idee
Ja, immer noch hello, ne? Also der Plus-Operator ändert nichts.
Der Plus-Operator nimmt einen String und noch einen String und liefert
euch ein Ergebnis, was die Zusammenfugung dieser beiden Strings ist.
Aber es wird nichts geändert. Das ist ja so
ganz typisch für Werte, wie so in oder stringen,
dass da eben die Operationen nichts ändern.
Wir können ja mal ein Gegenbeispiel nehmen, sagen wir doch,
wir nehmen mal eine Liste, ja?
You, Arilist von String. Irgendwie so. Genau,
wenn ich irgendwie keine Lust habe, das in eine Variable reinzustecken,
dann tut diese Jay-Shame mir das in eine Variable namens Dollar 7. Warum nicht?
Und wir können auch mal gucken, keine Ahnung,
wie viel ist denn jetzt da drin?
Dollar 7.zahlst zum Beispiel. Ihr seht, da ist
noch nichts drin
Null heißt ja null Elemente. Oder wenn ich fragen würde,
du hast Dollar 7. ist MT,
dann würde er mir sagen, ja, ist leer.
Und wenn ich jetzt hier zum Beispiel sage,
ich will doch was hinzuzufügen, sagen wir mal, super.
Was ist jetzt das Ergebnis dieses Ausdrucks?
Was kommt raus, wenn ich an einer Liste was hinzufüge?
Ja. True. Richtig. Warum das denn?
Hatten wir das mal in SE1? Ich glaube ja,
Eine Collection antwortet mir bei Ed immer, ob das geklappt hat, das hinzuzufügen.
Hier kommt also nicht raus, die Liste, die irgendwie super enthält.
Aber wenn ich jetzt nochmal frage, was ist denn jetzt
in dieser Liste drin, dann hat die Liste sich geändert.
Die Liste war eben noch leer, dann habe ich
was hinzugefügt und jetzt ist was drin in der Liste.
Das ist völlig anders, als es hier oben mit dem Plus-Operator war.
Das ist sowieso halbwegs verständlich. Und irgendwie scheint es auch intuitiv zu sein,
dass Listen irgendwie wachsen und sich ändern mit der Zeit.
Und ich wollte mal als kleinen Kontrast zeigen,
dass es in den letzten Jahren so den Trend gibt,
Auch Listen, nicht notwendigerweise als veränderliche Dinge anzusehen.
Ich mache ja immer ganz gerne Werbung für alternative Programmiersprachen
oder dass ihr mal über den Tellerrand hinausschaut.
Also wenn ich jetzt zum Beispiel hier sage,
ich will mir eine Liste anlegen, wo die Zahlen 3,5 und 7 drin sind.
Ja, das ist jetzt einfach mal so ein anderes Syntax,
das ist ja egal. Ihr seht also,
die Variable A ist dann eine Liste gebunden mit den Zahlen
3,5 und 7. Ich habe euch das nochmal getestet.
Was steckt denn ein A drin? Ah ja,
die Zahlen 3,5 und 7. Das ist jetzt einfach,
wenn dich das interessiert im dritten Semester, macht ihr,
glaube ich, auch irgendwas mit einer ähnlichen Programmiersprache.
Okay, und ich kann jetzt zum Beispiel sagen,
Ich will an die Liste A, da soll auch noch irgendwie zwei rein.
Das sollen vielleicht Primzahlen sein oder so. So. Jetzt gucken wir
mal. Ich habe jetzt hier also eine Liste erhalten,
wo die zwei auch tatsächlich drin ist.
Hier seht ihr sie. Ich habe also die Liste genommen
mit den Zahlen 3,5 und 7, habe gesagt,
ich brauche auch noch die zwei.
Und dann ist an der Liste entstanden,
wo die zwei jetzt eben auch drin ist.
Aber die ursprüngliche Liste ist immer noch so wie vorher.
Das ist also anders als in Java. Java sage ich
, hier ist meine Liste, pack es rein.
Dann hat sich jetzt die Liste geändert. In dieser Programmiersprache ist es so,
ich habe eine Liste und ich will daraus eine neue Liste machen,
wo dann auch noch die zwei,
drei ist.
Das ist eine andere Sicht auf Sammlung
Okay, das heißt jetzt nicht, dass das besser ist,
sondern dass es das eben auch gibt.
Kann man eben so oder so sehen. Gut,
dann schließe ich das jetzt mal nur mal eine kleine Demonstration,
dass das alles nicht so selbstverständlich ist, was wir hier machen.
Das schließe ich mal auch, kann ich das auch machen,
ja. Okay, dann starte ich mal Eclipse.
Ja, und schau mal kurz auf den Fahrplan,
also wir werden eine Klasse Bruch zusammen implementieren.
Genau, wir werden das testgetrieben machen,
weil es immer ganz nett ist, zu schauen,
wie will man denn überhaupt diese Bruchklasse verwenden.
Dafür eignen sich Testklassen auch ganz gut,
nicht nur um die Korrektheit halbwegs sicherzustellen.
Das schließen wir mal alles
Sondern auch, um sich über die Verwendung Gedanken zu machen.
Habe ich das angeklickt, ja.
Gut, dann mache ich doch mal ein neues Projekt.
Ein Java-Projekt, wie wollen wir es nennen,
wenn dann jetzt irgendwann mal so ein Fenster auffloppt,
da ist es, nennen wir das Brüche.
So, okay. Und dann mache ich jetzt erstmal,
wir sind jetzt keine Hardcore-Test-First-Leute, ich mache erstmal meine Java-Klasse,
nennen Sie mal Bruch.
Und dann mache ich anschließend meine Testklasse.
Normalerweise hätte ich die Testklasse ja zuerst schreiben müssen.
Okay. Oh, ich habe vergessen, Budget zu sagen, Budget.
Ich gebe es zu sagen, dass es eine Testlasse sein soll.
Ich glaube, ich lösche die mal eben und mache das nochmal neu.
Dann muss ich nicht so viel von Hand schreiben.
Also neuer Versuch. New, jetzt irgendwo CJ Unit,
da haben wir es. Bruchtest. Ja,
J. Unit 4 will ich haben, dankeschön.
Das hätte ich sonst nämlich alles von Hand machen müssen,
seht ihr. Okay. Gut,
wenn wir jetzt zum Beispiel die Klasse String testen würden,
dann würden wir jetzt wahrscheinlich gerne sowas schreiben wie,
keine Ahnung, String A ist gleich Hello, so wie eben.
Und vielleicht, keine Ahnung, dann würde man sagen,
Sir Equels, ich erwarte, dass Hello World rauskommt,
wenn ich irgendwie A plus World berechne
Das ist irgendwie so, das wären,
aber die Klasse String wollen wir ja nicht testen.
Wir wollen ja unsere eigene Klasse Bruch testen.
Also können wir uns mal überlegen,
was wäre denn jetzt der äquivalente Testwahl für unsere Klasse Bruch?
Flammen wir auf Vollbild. So. Ja klar,
also ich meine, wenn ich mir den Typ Bruch definiert habe,
kann ich ja eine Variable von dem Typ definieren.
Das ist ja schon mal kein Problem. Oder nenne ich
den vielleicht x die Variable, das ist ja egal.
Ja, und jetzt haben wir schon ein riesiges Problem.
Also in Java sind ja Strings so spezial unterstützen.
Ich kann die einfach in so Gensefüßchen schreiben.
Das wird jetzt mit meinem eigenen Typ nicht so einfach.
Ich muss also irgendwann
diese Exemplare rankommen
Jetzt ignorieren wir erst mal dieses Verbot, das New benutzen zu dürfen.
Ich mache es jetzt erst mal und gleich werden wir das dann entfernen.
Also ich erzeuge mir erst mal ganz so,
wie wir es kennen, ganz normalen Objekt mit diesem New.
Und was würde man jetzt sinnvollerweise übergeben an diesen Konstruktor?
Wenn es um Brüche geht, wisst ihr, was ein Bruch ist?
Ja. Zähler und Nenner. Noch mein Lieblingsbruch ist drei
Viertel. Nehmen wir noch mal drei Viertel. Okay,
das geht jetzt natürlich noch nicht, weil es diesen Konstruktor nicht gibt.
Dann sage ich jetzt, ihr klebt es einmal,
bitte generiere mir doch mal den Konstruktor.
Hier. Okay, hier ist der Konstruktor,
vielleicht mal einen schöneren Parameternamen,
sagen wir mal Erzähler und Nenner
Wie viele Buchstaben hat Nenner sechs? Und Zähler hat sieben,
das finde ich nicht so schön symmetrisch, ich nehme mal lieber sechs.
So, was tue ich jetzt sinnvollerweise in diesem Konstrukt?
Also diese Zahlen, die ich jetzt reinstecke, zähle und ändere,
die verschwinden ja, nachdem der Konstruktor durchgelaufen ist.
Was ist so ein Standardmuster, was man gerne macht,
mit den Parametern in so einer Klasse,
weil man sie sich irgendwie merken muss.
Tja. Und dann zuweisen. Kann ich das nicht irgendwie
von alleine machen? Kann ich ja nicht irgendwie sagen.
Source, General Constructure, schade, ich dachte,
das würde ich von alleine.
Na gut, also Zähler,
gleich Zähler
Man kann damit das hoffentlich generieren. Schauen wir mal.
Genau. Sehr schön. Und dann noch, ja.
Und dann noch, nennen wir gleich Nenner.
Das bitte mir auch generieren, das Feld. So. Ich
weiß nicht, warum immer so komische Leerzeilen darüber sind.
Macht das schon mal so halbwegs Sinn? Ich glaube ja
. Was haben wir jetzt erreicht? Wir haben zumindest schon
mal erreicht, dass das jetzt übersetzbar ist. Ja,
der Test beschwert sich hier an dieser Stelle nicht mehr unter der Compiler nicht.
Und jetzt bin ich bei diesem Ashird Equals.
Ja, rumrechnen will ich ja noch gar nicht damit.
Vielleicht hätte ich hier eher so was sagen sollen wie,
ich gehe davon aus, dass zum Beispiel das erste Zeichen von A dieses Haar ist.
Das ist los, lieber Computer. Ich habe da noch
ein bisschen getippt. Da kommen jetzt die einzelnen Buchstaben.
Okay. So, so in der Richtung. Ich habe
irgendwas zusammengesetztes und will mir so die Einzelteile rausholen.
Das würde ich hier auch gerne machen. Was wäre denn
hier so als Testinfo? Wo was besteht denn dieser Bruch?
Also ich, ja. Genau, aus Zählern, Nenner.
Also ich will irgendwie sowas haben wie vielleicht gibt Zähler,
so, ja, und Keep Nenner.
So, das macht doch irgendwie Sinn, oder?
Da nehme ich jetzt mal diesen String hier oben weg
Das heißt, ich teste dich an dieser Stelle,
ob der Konstruktor richtig funktioniert und ob es diese beiden gibt,
Methoden, die es noch gar nicht gibt,
dass die dann auch richtig funktionieren werden.
Oh, ach, ich habe vergessen, das auf dem
Objekt aufzurufen. X.x. So, ne? So,
jetzt müssen wir das hoffentlich in der richtigen Klasse generieren.
Richtig. Nein, da soll ein Int zurückkommen.
Okay. Und da gebe ich jetzt mal den Zähler zurück.
Das ist ja einfach nur Standard, so ein paar blöde Ghetter und Setter.
Das ist jetzt ja hoffentlich nicht überraschend für euch.
Das ist ein Int und da gehen wir mal
den Nenner zurück
Und dann ist jetzt die Hoffnung,
dass der erste Testfall schon mal durchläuft,
wie wollen wir den mal nennen, Konstruktor und Ghetter oder so.
So, das will ich jetzt ausführen, wie mache ich das denn?
Rechte Maustaste, Run as, wo es mein Run ist.
Nein, nicht die Bucks, sondern Run as J. Unittest.
So, und da ist schon mal unser erster grüner Balken,
das war schon mal ganz nett.
Also ich kann mir schon mal zumindest solche Brüche irgendwie,
ja, erzeugen, das ist irgendwie blöd,
eigentlich will ich das ja nicht
Also wir hatten ja schon gesagt,
wir nehmen Stadtkonstruktoren eigentlich lieber Fabrikmethoden. Das heißt,
ich nehme jetzt mal hier dieses Public weg und schreibe da mal einen Private hin,
weil irgendwie werden wir uns die natürlich intern immer noch erzeugen müssen,
jetzt in meine Zeilennummern schon wieder komisch.
Ich schließe einmal die Testklasse. Wie sieht ein Fabrikmethod aus? Sie sollte Public sein,
sonst kann sie von außen keiner benutzen, dann ist sie Static,
dann gibt sie einen Bruch zurück und jetzt können wir uns einen Namen ausdenken.
Bruchfabrik? Ja, ich nenne es einfach mal klassisch heißen,
die heißen gerne das Delect oder Value Off oder so,
keine Ahnung,
dann übergibt man da
seine Informationen
Und das sieht jetzt erst mal ein bisschen nach unnötig Aufwand
aus. Aber ihr werdet in der Zusatzaufgabe sehen,
die ihr, wenn ihr Zeit habt, erledigen könnt,
dass man hier auch durchaus andere Dinge reinschreiben kann.
Momentan ist es ja ziemlich blöd. Also ich habe jetzt
diesen Konstruktor Private gemacht und dann diese öffentliche Fabrikmethode ruft jetzt einfach nur den Konstruktor.
Das scheint ja eine unnötige Indirektion irgendwie zu sein.
Aber in dieser Zusatzaufgabe könnt ihr euch überlegen, hey,
kann ich mir nicht intern irgendwie eine Area anlegen,
wo die wichtigsten Brüche drin sind?
Und dann kann ich welche von denen rausreichen,
man muss hier nicht jedes Mal neu erzeugen.
Vielleicht kommen wir sogar heute noch dazu,
wenn wir da genügend Zeit für haben.
Okay, aber das akzeptieren wir jetzt erst mal,
dass es diese öffentliche Fabrikmethode gibt.
Wie benutze ich die denn jetzt? In meinem Test.
Also New Bruch geht jetzt ja nicht mehr.
Wie ist denn die Synthese meine statische Methode aufzurufen?
Keiner eine Idee. Soll ich einfach mal anfangen?
Bruchpunkt, wo ist der Punkt, da ist er.
Select. 3, 4. Ja, so ruft man statische
Methoden auf. Habt ihr schon mal eine Statusmethode geschrieben?
Sonst übt es vielleicht mal ein bisschen. Ja. Okay,
und jetzt sind irgendwelche Theoretiker zufrieden, weil jetzt hier dieses New nicht mehr auftaucht.
Dann zieht das nicht mehr so ganz aus,
als würde man sich in Objekte zeugen.
Gut. Natürlich ist es ein Java-Objekt im Hintergrund,
Okay, das ist jetzt alles noch nicht so wahnsinnig spannend.
Wir können noch mal einmal ganz kurz gucken. Ja,
wir haben also diese Exemplar, weil wir haben den,
wir haben den Konstruktor,
das haben wir schon hundertmal geschrieben in der Form,
den haben wir jetzt versteckt mit der Fabrikmethode und wir haben diese beiden Ghetter.
Also fachlich ist noch nicht so wahnsinnig viel passiert.
Das scheint also alles Zeug zu sein, das man schreiben muss,
nur weil es jetzt eben ein Fachwert ist. Könnt ihr euch vielleicht vorstellen,
wenn man irgendwann in Java schreiben kann, nicht irgendwie Claas Bruch,
sondern Value Claas Bruch und dass einem dann dieses ganze Zeug generiert,
das wäre doch vielleicht irgendwie ganz nett.
Okay, was habe ich denn jetzt als nächstes auf meinem Plan?
Konstruktor? Ghetter, Select to String, genau. Also,
wenn man so ein Ding mal auf die Konsole schreibt,
das ist jetzt irgendwie komisch, dass ich das in der Testklasse mache,
aber es ist jetzt nicht so schlimm.
Also wenn ich dieses X-Ma hier auf die Konsole schreibe,
während der Test durchläuft, Dann sieht man,
dass das irgendwie nicht so hübsch ist, ja.
Brüchelpunktbruch als 7366E 9ADB. Das ist irgendwie, also da hätte ich gerne,
dass da sowas steht wie 3 durch 4 oder so.
Wie kann ich denn erreichen, wenn ich einen Bruch auf
die Konsole schreibe, dass dann was hübsches erscheint,
anstatt dieser komische, merkwürdige String mit diesem Klammerhafen?
Habe ich das irgendwie beeinflussen? Also das hier hat mit dem Hashcoot zu tun,
aber wenn wir den Hashcoot jetzt neu definieren,
dann wird da einfach nur eine andere Zahl stehen.
Also ich will wirklich,
dass da insgesamt in der ganzen Zeile steht,
3 Schrägstrich 4 hat da immer eine Idee,
wie das gehen könnte
Ja. Korrekt. Das ist die korrekte Antwort. Also,
man kann ja in Java die To-String-Methode überschreiben, nicht wahr?
Das geht in Aclips relativ einfach. Was will ich machen?
Ja, wir können auch mal gucken, was passiert,
wenn man das nicht macht. Ich glaube,
das haben wir schon mal gemacht, aber ich mache es,
falls es so viel Spaß gemacht hat, einfach nochmal.
Hier seht ihr so, dass To-String aus Java Langup checkt.
Das guckt also einfach nur, wie heißt die Klasse,
dann klebt es dann Klammeraffen hinzu und dann klebt es da
den Hashgoat in den Hexer, die Zemana schreibt,
also dahinter.
Also genau das, was wir eben gesehen haben,
aber das wollen wir ja nicht.
Gut,
hallo,
weg damit
Das heißt, hier kann ich jetzt nicht,
was soll ich denn jetzt hier stattdessen schreiben,
wenn ich drei Schrägstrich 4 da stehen haben will.
Soll ich jetzt einfach schreiben, drei Schrägstrich 4?
Das ist ja allgemein wahrscheinlich nicht so sinnvoll. Was würdet ihr denn
da allgemein hinschreiben? Ja. Genau, also andersrum,
Zähler plus zack. Plus Nenner. So, ne? Gucken wir mal ganz kurz,
wenn wir jetzt unseren Test ausführen,
wenn ich dann meine Konsole sehe, genau,
dann schreiben wir doch da gleich mal einen Test für,
nennen wir das doch mal,
oder ich schreibe es da drunter,
dann ist es chronologisch irgendwie
ein bisschen nachvollziehbarer
Test to String. Kann ich also sagen. Achso,
und was ich immer ganz gerne mache,
ist dieses Dreiviertel will ich mir nicht ständig neu selekten,
das nervt mich irgendwie.
Ich packe das mal noch hier oben. Zack. So,
also ich erwarte, dass Dreiviertel rauskommt,
wenn ich auf X to String aufrufe, ja.
Dass ich immer alles seht hier ist. Das macht
das Sinn. Vielleicht nenne ich das X mal anders.
X ist kein schöner Name für ein Feld, auch nicht in Testklassen.
Mit Dreivierteln nennen wir es mal, ja.
Das versteht auch hoffentlich jeder. Also wenn ich auf Dreiviertel
oder String aufrufe, sollte da dieser String mal rauskommen.
Dann führen wir das doch gleich wieder aus
Ja. Achso, ist dieses System halt Pünktler noch irgendwo,
das will ich natürlich nicht. Weg damit nochmal ausführen.
Genau, Balken ist gewöhnen, das ist doch schön.
Gut, das haben wir jetzt gemacht.
Was wollte ich noch machen? Genau,
jetzt wollen wir endlich mal was Sinnvolles tun, also was fachlich ist,
wie ich will mal was Fachliches mit euch machen.
Bis jetzt ist das ja alles sehr technisch, was wir hier gemacht haben.
Getter, Konstruktoren, Fabriken, to String.
Ich will jetzt mal Brüche miteinander multiplizieren können.
Und dazu schreiben wir mal zuerst im Testfall Public Void,
Multi-Publikation, nennen wir das mal den Testfall.
Vielleicht sollten wir dazu noch einen zweiten Bruch mal hier oben anlegen.
Das ist sonst ein bisschen langweilig. Nehmen wir mal eineinhalb
. So, ne? Genau. Ich will jetzt also
hier, ich kann das mal auf Deutsch hinschreiben.
Also hier soll quasi drei Achtel. Tja, also ich
schreibe es jetzt wirklich mal auf Deutsch hin, ja?
Drei Achtel, so erwarte ich, dass es hier rauskommt.
Und dann irgendwie quasi drei Viertel mal eineinhalb. Ja,
so, das ist natürlich kein Java. Okay, also
das ist irgendwie klar. Hier kann ich ja sagen,
ja, was kann ich denn jetzt hier machen?
Kann ich einfach diesen Multiplikationsopparator nehmen? Es gibt ja durchaus
Sprachen, wo das geht, ne?
Ist das irgendwie erlaubt? Was sagt Java da
Tja, den gibt es auf Brüchen nicht,
aber leider kann ich ihn auch nicht definieren.
Also es gibt Sprachen, wo ich tatsächlich
die Multiplikation für eigene Typen mit diesem Operator definieren kann.
Das geht in Java nicht. Was haben wir denn für eine Alternative?
Also ich habe irgendwie zwei Brüche, ich will sie miteinander multiplizieren.
Mit dem Sternchen geht es nicht, ja. Genau,
und diesen Code tut man in eine Methode rein.
Wie wollen wir die Methode nennen? Ich glaube,
ich wollte sie Malen nennen. Das dann liest es sich
so schön. Die gibt es natürlich noch nicht.
Und wie kann ich jetzt hier formulieren,
dass ich glaube,
dass da
drei Achtel rauskommt
Wie sage ich, der Bruch mit dem Wert Drei-Achteln?
Gibt es irgendeine Methode, wo ich zwei Zahlen reinstellen kann und kommt Bruch raus?
Irgendjemand war der, ja? Genau. Ich kann nur sagen,
Bruch.select, 3,8. Ja, das ist mein Testfall.
Hier ist ein Leerzeichen zu viel. Ist das nachvollziehbar,
wenn ich diese Methode, die es noch nicht gibt,
auf dreiviertel Aufruf und eineinhalb übergebe,
dann sollte da der Bruch 3,8 rauskommen.
Okay, dann sage ich, ihr klippt mal,
dass ihr das bitte generieren sollt für mich.
Zack. Er glaubt mal wieder, dass sein Objekt zurückkommt,
das ist Quatsch. Das ist auch kein besonders sinnvoller Parametername,
den nenne ich immer gerne That.
Vielleicht habt ihr eine Idee, warum
Wegen Wiss. Genau. Also wenn ich nochmal den Klienten zurückgehe,
immer dann, wenn ihr in Java einen Methodenaufruf seht,
das erkennt ihr ja daran, dass ihr so ein Punkt steht.
Wir haben das eine Punktnotation genannt. Das, was vor dem Punkt steht,
ist dann ja in der Methode mal die Wissreferenz.
Ja, und das, was hierhinter steht,
da könnt ihr so euch selber überlegen, wie ihr das nennt.
Das ist ja einfach nur ein Parameter. Das habe ich
jetzt mal Vad genannt. Okay. Ja, wie rechne
ich das denn jetzt aus? Wohnt es erstmal an dem
konkreten Beispiel, haben wir uns irgendwie auf Papier klarmachen.
Wir haben ja so ein kleines Kladdepapier.
Also wir hatten gesagt, ich will drei Viertel multiplizieren mit
Ein halb. So. Was muss ich denn jetzt rechnen,
um das Ergebnis zu wissen? Wie rechnet man das denn
aus? Weiß das noch jemand aus der Grundschule?
Das ist schon lange her, ne?
Wie rechne ich das? Was kommt da raus?
Also den Berufsstich kann ich schon mal hinschreiben.
Ihr könnt es auch einfach in den Raum rufen,
wenn ihr euch nicht traut, euch zu melden.
Drei Viertel, drei Achtel, Dankeschön. Ja,
wenn euch die Zwischenschritte nicht klar sind,
also man rechnet hier quasi dreimal eins und hier
rechnet man viermal zwei,
nicht wahr
Gut, das müssen wir jetzt also einfach allgemein machen.
Wie komme ich denn an diese drei ran?
Ich bin jetzt also hier in dieser Methode mal,
ich habe also meine Entwissreferenz und ich habe diesen Parameter.
Wie komme ich jetzt an diese drei ran?
Wo steht die drin? In welcher Variable? Ja.
Das wäre diese Eins, oder? Diese Investoren,
also ich könnte sagen this.zähler, zack, mal,
und jetzt hast du gesagt that.getzähler,
aber ich kann tatsächlich auch hier direkt auf den Zähler zugreifen.
Das ist nicht verboten in Java
Oh, jetzt bin ich schon bei Return.
Ich mache das vielleicht mal in mehreren Zwischenschritten. Soll ich
das mal so machen? In Set steht jetzt drin,
dreimal eins quasi, ja, also drei.
Okay, wie geht es weiter im Text?
Wie komme ich jetzt an diese beiden Zahlen dran?
Könnt ihr das irgendwie nachvollziehen? Keiner. Zu einfach,
oder? Dann schreibe ich selber hin. Also der Nenner
ist der eigene Nenner, mal der andere Nenner.
So, jetzt gebe ich doch keinen Bruch zurück.
Was mache ich denn jetzt? Ich habe jetzt
diese beiden Zahlen ausgerechnet,
Jetzt passiert das. Sehr schön, du hast vorschlagen,
dass wir kürzen. Ich gucke mal ganz kurz,
ob ich das auf meinem Zettel habe,
sonst schreibe ich das doch mal ganz kurz rein.
Ich habe es drauf. Können wir gleich machen. Ja,
kürzen ist eine gute Idee, aber das machen wir jetzt noch nicht.
Ja, also ich habe jetzt diese beiden Zahlen nicht, wa?
Also ich habe jetzt die drei ausgerechnet und ich habe die acht ausgerechnet.
Wie mache ich jetzt aus der 3 und der 8?
Drei achte. Dahinten meldet sich jemand.
Wieder mit
Ich habe den Rest nicht verstanden. Select, genau,
ne? Z und N. Okay? Wer konnte das nachvollziehen
, diese Methode mal? Okay, das beruhigt mich,
weil ihr seid so ruhig heute. Gut, beruhigend.
Gut, wir haben ja schon den Test, nicht wahr?
Genau, dann können wir den jetzt ja einmal ausführen.
Oh, was ist denn jetzt los? Kann man mal
kurz gucken. Okay, also expected, drei Achtel. Das ist ja,
weil wir hier, hier tut man immer das rein,
was man expected als ersten Parametern,
das hört X, was nicht wahr.
Also, wir erwarten, dass der Bruch drei Achtel rauskommt
Und was ist stattdessen rausgegangen? Haben wir uns verrechnet?
Ach, guck mal, was stattdessen rauskommt. Ja,
wir dachten eigentlich zu 3, 8. Roskan Rolf stattdessen ins Dreiechtel rausgekommen.
Da ist der Test fehlgeschlagen. Ja, es klingt ja
erstmal unlogisch. Kann mir das jemand erklären?
Ja. Du sagst, Equals Vergleich, die Identität.
Wir können ja mal gucken. Tatsächlich kann ich da nicht
mit 11, 3 irgendwie reingehen. Oh, schade,
ich habe keinen Quelltext zu Dray und 4. Schade.
Also es ist tatsächlich so, dass es ist, Sir
Equals ruft intern Equals auf. Ja. Wir haben noch
keine Equals, richtig.
Sehr gut
Wir haben noch keinen Equals. Wie mache ich das denn
jetzt? Ich kann es ja mal so machen,
dass ich ihn auch hier den Fehler seht.
Sorry, nochmal bitte. Aber du würdest gerne erstmal kürzen.
Ja, es steht auf meiner Liste hinter den Equals,
also wir kommen gleich dazu. Keine Sorge,
wir kommen gleich dazu, ich habe es im Hinterkopf.
Also ich habe meinen eigenen Buch, ich habe den anderen Buch.
Kann ich jetzt nicht einfach sowas sagen wie This.zähler ist That.zähler
und This.nenner ist That.nenner.
So irgendwie
Das scheint auch erstmal irgendwie sinnvoll zu sein, oder?
Ich führe den Test nochmal aus. Hat leider nicht geklappt
, das ist derselbe Fehler, ne?
Drei Achtel, drei Achtel, okay. Ja. Wer
sieht den Fehler? Was habe ich da falsch gemacht?
Einer sieht's, nur ein einziger. Zwei Sehens,
drei Sehens, alle haben schon mal was gesagt.
Ja, dann nehme ich den dritten.
Hast du dich gemeldet oder nicht?
Wir müssen ja auch Equals benutzen, sagst du?
Also du sagst, das ist falsch, dass wir hier
das gleich gleich verwenden. Die Antwort ist leider nicht korrekt,
denn Zähler und Nenner sind ja vom Typ Int,
und da gibt es nur das Gleichgleich,
da gibt es gar keine Equals.
Also bei primitiven Typen gibt es keine Equals. Wer hatte
sich noch gemeldet? Du hattest dich, glaube ich,
noch gemeldet, oder? Du wolltest dasselbe sagen. Und
du? Okay, das geht in die richtige Richtung.
Man muss Equals überschreiben. Viele Leute denken immer,
das heißt, ich muss hier Ad Overwrite hinschreiben.
Das macht er eigentlich keinen Unterschied. Aber der Compiler warnt
mich jetzt, dass es gar kein Überschreiben ist
Das ist nicht die Equiels-Methode, die ich hier versuche zu überschreiben.
Warum nicht? Ganz hinten. Richtig, der Übergabtyp muss
aufcheckt sein. Den kann ich nicht einfach beliebig anpassen.
Also hier muss ich tatsächlich ein Object übergeben.
Ich nenne das mal so. Und dann ist es nicht mehr
so ein einfacher Einzahler. Wisst ihr noch, wie man
Equiels überschreibt? Das haben wir euch doch in SE1 beigebracht.
Also ich muss erst mal prüfen, ist das überhaupt ein Bruch?
Und wenn es ein Bruch ist, dann muss ich sagen,
Typzusicherung,
erinnert ihr euch noch daran
Also das hier ist der, schreibt das mal drüber, Typ Test.
Und das ist die Türzusicherung. Hatten wir alles in SE1.
So, hups. Ist aber immer noch nicht übersetzbar.
Warum nicht? Da fehlt irgendwie noch ein Return.
Also wenn dieses Return wird ja nur ausgeführt,
wenn diese Bedingung wahr ist und wenn sie falsch ist,
weiß Java nicht, was hier zurückgegeben werden soll.
Wir geben mal False zurück. Also wenn ich versuche,
einen Bruch mit einem Konto zu vergleichen,
dann sollte da
False zurückkommen.
Gut, dann schau doch mal, ob das jetzt geht.
Ah, schon besser. Jetzt hat er das also verstanden
. Das ist also ein ganz gemeiner Stolperstein.
Ich komme ja mit dem Vorbild irgendwie immer durcheinander.
Ganz gemeiner Stolperstein. Man muss hier Object entgegennehmen.
Man kann nicht was Spezielleres nehmen. Ist halt nun mal
leider einfach so. Okay, gut. So,
jetzt kommen wir, glaube ich, schon zu einem kurzen,
oder? Soll ich mal kurz in mein Kochrezept gehen?
Das war Equals und jetzt kommt Kürzen
, genau
Genau. Wollen wir dafür nochmal irgendein anderes Beispiel nehmen?
Ich glaube, wenn man so sagt, ich glaube,
was hatte ich denn letztes Jahr genommen?
Ich glaube, fünf Sechstel hatte ich genommen.
Fünf Sechstel. So, ich muss da mal so eine
zusätzliche Lerntaste, das will ich nicht.
Und das kann ich auch mal darunter schreiben. Also,
wenn ich drei Viertel multipliziere mit, von, nee.
Hallo? Fünf Sechstel? Ja,
was kommt da raus
Ja. Also dreimal fünf bis auf 15, oder?
Und viermal sechs ist 24, so. Kann man das kürzen?
Können jemanden vorschlagen, wie man das kürzen kann, ja?
Fünf Achtel, wenn ich durch drei jeweils teile.
Ja, das sieht gut aus. Okay. Das wird jetzt
natürlich fehlschlagen, nicht wahr? Also vielleicht können wir das
ja mal sogar in den eigenen Testfall tun. Ja,
ich mache das, tut das mal in deinen eigenen Testfall,
weil das ja irgendwie konzeptionell was anderes ist.
Nennen wir das doch mal Multiplikationen gekürzt oder so gekürzt
Okay, dann würde ich jetzt erwarten,
dass dieser eine Test fehlschlägt, aber nicht der andere.
Genau, Multiplikation gekürzt hat nicht funktioniert. Sehr schön.
Okay, wo baut man jetzt diese Kürzung ein?
Also man könnte sich überlegen, ich tue die jetzt speziell in dieses Mal rein.
Ich finde es irgendwie ganz nett, wenn man,
ja, wenn man das Programm sozusagen so absichert,
dass nur gekürzte Brüche überhaupt selektiert werden können.
Also wenn ich jetzt zum Beispiel selektiere, 20 Zehntel,
dann sollte ich sofort zwei Ganze bekommen.
Wollen wir das dann einfach mal hier in den Konstruktor reintun?
Dann ist garantiert, das geht ja immer über diesen Umweg,
dass es auf jeden Fall gemacht wird.
Wie kürze ich denn ein Bruch? Weiß das noch jemand
Sehr gut, geht zu dir. Ich weiß gar nicht,
ob es die in Java schon gibt, ehrlich gesagt.
Wir können einmal ganz kurz gucken, ob es da
sowas gibt wie Greatest Comment Devisor oder so vielleicht.
Aber ich glaube, die gibt es tatsächlich nicht.
Da müssen wir uns hier halt selber schreiben. Macht nichts
, kriegen wir hin. Also, machen wir uns mal
eine kleine Hilfsmethode. Grüßt der gemeinsame Teile. So,
und dann ist es irgendwie so eine kleine rekursive Fingerübung,
wenn B. 0 ist, geben wir A zurück und ansonsten geben wir das Derby.
Ich weiß nicht, ob ihr das schon mal gemacht habt.
Das ist so, das ist Heißt ja nicht nur Algorithmus von Eukleed oder so?
Eukleed, ne? Algorithmus von Eukleed. Also wenn euch
das interessiert, warum da jetzt der größte gemeinsame Teil rauskommt,
schaut euch das einfach mal an.
Das ist unglaublich faszinierend. Ich habe mir da
schon viele für glückliche Stunden auf der Couch gemacht,
um einfach nur zu verstehen, warum das funktioniert.
So. Ja, jetzt können wir mal gucken,
wir benutzen, benutzen wir das schon irgendwo,
größter gemeinsame Teile wird noch nicht benutzt.
Wie können wir das jetzt hier sinnvoll benutzen?
Also ich kriege diesen Zähler und den Nenner reingesteckt und ich
will jetzt irgendwie erstmal den größten gemeinsamen Teil, aber bestimmt,
das kriegen wir doch hin, oder?
Ich rufe diese Methode auf, übergebe den Zähler und den Nenner.
Ups. Gut. So. Dann kommt da,
kommt da was zurück
Nennen wir das mal größter gemeinsamer Teiler.
Was mache ich denn jetzt mit dem größten gemeinsamen Teil?
Also in unserem Fall war das ja drei.
Was soll ich die drei jetzt auf die Konsole schreiben oder
was soll ich jetzt sinnvollerweise mit der drei machen?
Also wir hatten ja in dem Test, hatten wir ja gesagt,
naja, eigentlich kommt da ja 15, 24 raus,
aber wir wissen ja, dass das 5, 8 ist.
Wir kommen dann von 15, 24. auf 5,
8. Was haben wir da gemacht?
Was mit der 3 zu tun hat?
Da. Genau. So, ne? Ich bestimme also
den größten gemeinsamen Teil von 10 an und dann werden die
jeweils hier devidiert
Und die Tische, die gleichzeitig befreundet ist.
Wir teilen durch null. Ach so. Ja,
das könnte tatsächlich passieren. Guter Hinweis, den merken wir
uns mal. Okay, jetzt gucken wir erst mal,
ob dieser Testdurchlauf ja eben noch nicht durchlief.
Gut, jetzt läuft er also durch. Das ist doch
schön. Okay, das war so das Kürzen.
Was haben wir denn noch? Ah, ich will
auch addieren können. Kommt da noch was? Okay,
ich glaube, das addieren ist das das letzte wirklich Fachliche.
Wo haben wir uns das immer hin tun, das addieren?
Ach, hier ist Mal natürlich doch mal da drunter
Gut. Ach, ich habe den Test ja noch gar
nicht geschrieben. Wollen wir erst mal den Test schreiben?
Ich war etwas übereilig. Ich will also Addition haben,
testen. So. Ja, hat ja mal eine Idee,
welche von diesen Brüchen ich hier addieren will, soll.
Ach, ich nehme wieder drei Viertel und fünf Sechstel, oder?
Ich weiß noch nicht genau, was da rauskommt.
Ich muss uns gleich mal was überlegen.
Weiß ich noch nicht. Drei Viertel. Wie habe ich
die Methode eigentlich genannt? Ich will sie plus nennen,
kann ich ja gleich noch was noch erinnern.
Fünf, sechs. Habe ich die so genannt?
Ich weiß es
gar nicht
Ich gucke mal kurz. Nee, Ad habe ich
es gemacht. Das finde ich blöd. Ich will es
lieber plus nennen. Das gefällt mir besser. Ja,
was ist denn Dreiviertel plus fünf Sechstel?
Sollen wir wieder in unsere, auf unsere Klatte gehen?
Also ich will, das soll ein Plus sein.
So, tja, was kommt denn daraus?
Wie rechne ich das denn aus? Es muss erweitert werden.
Das klingt doch schon mal gut. Das heißt ja,
das Endergebnis wird unten viermal sechs stehen haben,
Dann müsste das oben sein, dreimal sechs, ups,
das war eine große sechs. Und dann hier viermal fünf
. Macht das Sinn, Mathematiker an die Front?
Okay. So, ne? Okay, das heißt,
ich muss also meinen eigenen Zähler multiplizieren mit dem anderen Nenner.
Und dann muss ich meinen eigenen Nenner multiplizieren mit dem anderen Zähler.
Das ist dann der neue Zähler. Und der neue Nenner
ist das Produkt der beiden Nenner. Das kriege ich,
glaube ich, hin. Ach so, ach so,
wir haben es noch gar nicht konkret ausgerechnet.
Das muss ich ja für den Test erstmal machen.
Was kommt denn da raus? Also unten ist 24,
das kriege ich hin. 18 und 20 ist 38,
ne? Ach so, du hast gleich gekotzt
1912 Uhr, richtig. Ich gucke mal, ich lasse
es jetzt erstmal ungekürzt. Mich interessiert einfach, ob das
auch funktioniert. Das habe ich letztes Jahr nicht gemacht.
Okay. Gut. Also, was hatte ich eben gesagt?
Der neue Zähler ist mein eigener Zähler, mal der andere Nenner.
Plus mein eigener Nenner, mal der andere Zähler.
So, und der neue Nenner ist mein eigener,
ne, Entschuldigung, Nenner, mal der andere Nenner.
Ja, und dann kann ich
das selekten
Das finde ich irgendwie ganz witzig,
also anhand von Beispielen kriegen wir das immer hin,
aber das dann so abstrakt formal hinzuschreiben,
das scheint irgendwie immer so ein kleiner Schritt zu sein,
aber das ist ja immer so mal programmieren.
Ich war so von den Beispielen zum Allgemeinen. Okay,
schauen wir mal, ob das jetzt funktioniert. Tja,
das funktioniert auch immer noch, das ist doch nicht schlecht.
Ja, dann haben wir immerhin,
haben wir es immerhin geschafft, zweifachliche Methoden zu implementieren.
Die Multiplikation von Bürschen und die Addition von Brüchen.
Der Rest ist ja alles nur technisches Gehuber. Okay,
ich glaube, es kommt noch mehr technisches Gehuber.
Das ist dann ja das, was sie dann
auch in der Übung sozusagen als Transferleistung umsetzen könnt.
Ich will nochmal einen Test schreiben, Ja,
ich weiß noch nicht genau, wie ich den nennen will,
ist auch erstmal egal.
Und zwar will ich Folgendes machen. Ich möchte mir
ein Hashtag erzeugen, okay? Ein Hashtag von Brüchen?
Warum nicht? Wie wollen wir das mal nennen?
Brüche. So, da ist ja noch nichts drin,
dann fügen wir mal was hinzu.
Tun wir doch mal. Ich nehme immer gerne Pi.
Oh, Schwachsinn. Singular. So, ja? Okay,
also ich habe das leere Set,
dann füge ich eine Näherung von Pi hinzu
Und dann gehe ich mal davon aus,
dass diese Näherung von Pi da drin ist.
Wie mache ich das mal in Java-Contains? Genau. Ey,
was habe ich jetzt gemacht? Entschuldigung, völliger Schwachsinn.
Völliger Schwachsinn. Es gibt leider keinen Assert Contains. Das ist
ein bisschen schade. Vielleicht gibt es das irgendwann mal.
So muss ich es, glaube ich, machen.
Macht das Sinn, was ich hier geschrieben habe?
Ich gehe davon aus, dass in der Menge Brüche diese 22 Siebtel drin sind.
Okay, das habe ich, glaube ich,
also ich verstehe zumindest, was ich damit erreichen wollte.
Ich hoffe, es geht euch ähnlich
Hier ist der Test. So. Oh. Gut,
was ist der Fehler? Ja, gut,
er sagt einem halt, dass das nicht wahr war.
Also kann ich hier noch irgendwie reinklicken. Ja,
also dieser Ausdruck war nicht wahr, sondern dann wahrscheinlich False,
ja, was anderes bleibt ja nicht übrig.
Das ist ja irgendwie komisch. Ich will den Test vor allem mal kopieren.
Nennen wir das mal noch ein Coup dazu. Ich teste,
dass man nicht nur, ob der einmal drin ist,
sondern ich kann ja mal über alle,
kann ich nicht hier mit einer Foreig schlaf über alle rübergehen
Genau. Und jetzt mache ich hier mal eine Third Eatfills.
Ich gehe also davon aus, dass sozusagen alle Brüche,
die drin sind in meiner Menge, dass die diesem 22.7. entsprechen.
Ist das irgendwie nachvollziehbar? Wie oft wird diese Schleife durchlaufen?
Einmal, ich sehe den Daumen nach oben, richtig.
Hier ist die Menge leer, der würde sich
überhaupt gar nicht durchlaufen. Jetzt habe ich einen hinzugefügt,
das heißt, ich gehe hier im Prinzip, ja,
einmal wird dieser Rumpf ausgeführt, ja.
Schauen wir doch mal, ob das durchläuft.
Das ist dieses hier, ne? Guck mal,
das läuft zum Beispiel durch, das geht.
Das heißt, die 22.7. ist wirklich drin,
aber wenn ich frage, ob die 22.7. drin sind,
sagt immer,
die ist nicht drin
Das ist irgendwie ein komischer, komischer Widerschau, oder?
Also es hat was mit dem Containt zu tun.
Die Frage ist, wie das herausgefunden wird,
ob der Bruch da drin ist oder nicht, ja?
Genau, die Hashcodes sind verschieden. Also der Hashcode,
der Hashcode von diesem Bruch ist ein anderer,
als der Hashcode von diesen Bruch.
Und ihr wisst ja noch, dass ein Hashset intern so aufgebaut ist.
Man hat so ein Arry, was immer gerne vertikal malen.
Und dann hat man diese Überlaufbehälter. Und dann ist vielleicht
der erste 22. Siebtel war irgendwo hier oben einsortiert.
Und der zweite 22. Siebtel, da hat er vielleicht hier
unten irgendwo geguckt, ob das da ist.
Also erinnert euch noch an SE1 als die eigene Hashsets implementiert habt.
Wenn man Hash-Code nicht vernünftig überschreibt, kann das nicht funktionieren.
Wir müssen also jedes Mal, wenn wir die Equels-Methode überschreiben,
das haben wir ja hier gemacht, hier.
Ja, ich schreibe euch mal so eine Regel auf.
Wenn A. Equels B gilt, dann muss A. Hash-Code,
gleich gleich B. Hash-Code gelten
Ja, und das ist momentan nicht der Fall.
Ich kann mir ja beliebig viele 22, 70 erzeugen,
die alle, ja, was ist denn der Hashcode von denen?
Das können wir uns gleich auch nochmal angucken.
Da werdet ihr sehen. Ich glaube, wir können nicht
in den Quelltext reingucken von dem Hashcode von Object.
Aber es ist so, dass die alle einen neuen Hashcode haben.
Das können wir auch noch mal ganz kurz gucken,
dass ich das jetzt nicht einfach so in die Luft verspreche.
Also, mache ich noch mal irgendeinen Quatschtest, nur damit er ausgeführt wird.
Was? Der heißt ja fast so wie ich,
das wollte ich heute noch auf die Tastatur rumhacken.
Also wenn ich jetzt hier sage, zum Beispiel,
Bruchpunktselect 22 Siebtel. Man muss das ja immer sehen,
sonst wisst ihr nicht, was in meinem Kopf los ist.
Achso, nee, ich will den Hashcott ausgeben, Entschuldigung.
Hashcott. Wenn ich das ein paar Mal mache.
Dann werdet ihr sehen, dass er jedes Mal was anderes rauskommt, hoffentlich.
Das seht ihr es, ne? Das hat einfach damit zu tun,
dass der Hashcott normalerweise von der Speicheradresse des Objekts abhängt.
Und jedes Mal, wenn ich einen 22-seklen Speicher ablege,
liegt es halt woanders und kriegt deswegen einen eigenen Hashcode.
Okay. Genau, ich muss es also überschreiben,
also kann ich das nicht auch irgendwie overright hashcode, genau.
Ich gucke mal kurz, ob man hier reingucken kann,
aber ich glaube,
es geht nicht
Native, ja. Also das ist irgendwie nicht in Java implementiert,
diese Hashcore-Methode, ja. Ist wahrscheinlich zu speicherner,
das geht an Wind, schauen wir nicht. Okay,
wie kann ich das denn jetzt erreichen,
wenn ich mehrere Bruchobjekte habe, wo jeweils 22 Siebtel drinsteht,
das ist dann hier dieselbe Zahl zurückkommt.
Also der Hashcore soll abhängen von dem Zähler und dem Nenner
und nicht irgendwie von der Speicheradresse, ja.
Also du willst es durcheinander teilen einfach? Und dann draußen Int machen,
also Zähler durch Nenner, das ist doch schon in, oder?
Genau, wenn ich Input individuiere, ist es in End.
Können wir machen. Also ich meine, diese Formel ist,
das ist eine mathematische Formel, egal welche Zahlen ich da reinstecke,
wenn ich die da mehrfach anstecke, wird immer dasselbe Ergebnis dabei rauskommen.
Ihr hättet das auch genauso gut addieren können oder multiplizieren oder
was man gerne macht, ist man multipliziert,
immer gerne mit Primzahlen und addiert dann die weiteren Informationen auf.
Das ist so die Standardlösung meistens. Also wenn ihr mal
zum Beispiel guckt, wie ist das zum Beispiel in der
Klasse String gelöst?
Können wir einfach
mal reingucken
Da werdet ihr irgendwo sehen, guck mal hier.
Könnt ihr euch mal eine Ruhe angucken,
das ist mit einer Vorschlafe gelöst,
dass man immer gerne sagt,
ich nehme irgendwie ein Stück Informationen und multipliziere es mit 31
und packe die nächste Information dazu und dann multipliziere ich das Ganze mit 31 und packe die nächste Information dazu.
Wenn ihr euch irgendeinen halbwegs wertvolles Java-Buch anschaut,
dann gibt es da so Kochrezepte, wie man eine Hashcock-Methode sinnvoll schreibt.
Meistens macht man es so. Okay,
dann testen wir das doch noch mal ganz kurz.
Ich kann mal diesen Quatsch jetzt, ach nee,
den lasse ich mal da und dann seht ihr das immer,
derselbe Hashcock zurückkommt.
Seht ihr, jetzt kommt immer 689 zurück,
weil 22 mal 31 plus 7,
offenbar 689 ist und alle unsere Testfälle sind durchgelaufen
Okay, ich weiß gar nicht, wo ich das jetzt mal offen lassen soll,
vielleicht mal die Tests oder den Bruch, ja,
über Tests muss ich, glaube ich, euch nichts erzählen.
Also immer eine kleine Zusammenfassung, wenn ihr also eigene Wertklassen schreibt,
die irgendwie Zusammenfassung anderer Werte sind, ja,
und nicht einfach nur eine einfache Aufzählung von vier Himmelsrichtungen oder so.
Oh, eine Sache habe ich noch vergessen, die sollten immer Final sein. Okay,
macht sie Final, dass sie sich nicht aus Versehen verändert,
dann, das ist eine Hilfsmethode,
die hat nichts mit Werten zu tun,
dann macht man es meistens so,
dass man den Konstruktor privat macht,
damit man von außen nicht dieses New sieht,
dann fühlt es sich weniger objektartig an,
dann gibt man immer gerne diese Factory-Methoden stattdessen nach außen,
damit man
auch mal irgendwie rankommt an diese Werte
Dann meistens will man an die Bestandteile reinkommen. Dafür gibt es dann diese Ghetta.
Dann ist es immer schön, wenn man zu String überschreibt,
dann sieht man, was Nettes auf der Konsole.
Dann sollte man auch fachliche Operationen anbieten in unserem Fall,
zum Beispiel Multiplikation und Addition,
damit es nicht einfach nur so ein dummer Rapper ist.
Und ihr müsst daran denken, Equals und Hashcore zu überschreiben,
weil sonst verhalten sich eure Werte komisch,
wenn ihr sie in Sammlung reinsteckt.
Das ist eigentlich so die Hauptmotivation.
Okay, bis nächste Woche.