5, 4, 3, 2,
1. Willkommen zur deutschen Hitparade mit Dieter Thomas Heck.
Wahrscheinlich auch jemand, den sie in ihrer Jugend nicht mehr kennengelernt haben.
Naja, mein Name ist wie immer Guido Gritzer,
heute Vorlesung 4, Business Assusual, Dreiviertelstunde Konzepte.
Und danach eine Dreiviertelstunde zugucken beim Denken schrägstrich programmieren mit Fred.
Heute. Heute geht's um zwei Themen,
die eng miteinander verbunden sind im Rahmen der Objektorientierten Programmierung.
Das erste Thema wird sein Parameterübergabe
Das werden wir uns mal konzeptionell so ein klein wenig anschauen,
was, wie man das verstehen kann und das zweite Thema sind dann so zusammenfassend vorausschauend.
Beides ein klein wenig. Welche Arten von Variablen wir in objektorientierten Programmen unterscheiden.
Und diese beiden Themen dienen dazu, ihnen so einen weiteren Mosaikstein,
einen weiteren Baustein des Themas Programmieren im Kleinen nahezubringen.
So, zur Sache. Sie haben jetzt schon so die ersten Wochen,
die sie sich jetzt mit Programmierung, mit Carol,
jetzt auch schon mit Java, beschäftigt haben.
Haben sich schon so kleinere Programme nicht nur geschrieben,
indem Editor, mit dem sie es zu tun haben,
sie haben diese Programme übersetzt.
Sie haben sie zur Ausführung gebracht, das heißt insbesondere,
dass sie auch von den Programmen den Klassentexten,
die sie geschrieben haben, haben sie Objekte erzeugt.
Und was da also abläuft innerhalb der Maschine,
ist also das, was also nicht nur umgangssprachlich,
sondern auch fachsprachlich so bezeichnet wird, das sind sogenannte Algorithmen.
So, das müssen wir uns jetzt nicht müssten,
aber das schauen wir uns jetzt mal um Wissenshorizont,
so ein wenig zu verbreitern.
Das schauen wir uns jetzt mal so ein klein wenig an.
Was sind eigentlich Algorithmen? Wie ist das so,
wie ist dieses Konzept ursprünglich entstanden und wie wird das heutzutage im Rahmen der Programmierung?
Wie wird dieses Konzept interpretiert? Sollte nicht interpretiert sagen,
sondern wie wird das, wie ist das heutzutage definiert?
So, zunächst mal, also Algorithmen sind benannte Folgen von Anweisungen.
Anweisungen haben sie kennengelernt. Das sind also zum Beispiel,
sind es Zuweisungen an Variablen,
also Wertezuweisungen an Variablen
So, diese benannten Folgen von Anweisungen
haben sie auch schon im Rahmen der Beschäftigung mit Carol,
haben sie schon kennengelernt, so den Begriff der Prozedur.
Ich komme gleich auch noch auf die genaue Definition von Prozedur,
sodass diese Folge von Anweisungen, die einen Namen hat,
stellvertretend für die Folge von Anweisungen aufgerufen werden kann.
So, eine Möglichkeit, um eine größere Menge von Problemlösungen
mit einer benannten Folge von Anweisungen durchführen zu können,
ausführen zu können, ist also die Parameterübergabe.
Und das ist jetzt so, wie gesagt,
das ist das erste Thema
Mit dem wir uns heute beschäftigen. Also wie kann man das so im Detail,
sich ein Verständnis dafür erarbeiten, was Parameterübergabe bedeutet,
wie das funktioniert, welche Effekte man damit erzielen kann.
So, kurz so ein Einschub, so historisch,
historisch und auch definitorisch, also zunächst mal definitorisch.
Was ist ein Algorithmus? Was wird darunter im Rahmen der Programmierung und
auch der Objektorientierten Programmierung als dieser speziellen Art von Programmierung,
was wird darunter verstanden?
So, die sehen hier diese kleine Bleiwüste,
eine Ein Algorithmus ist eine eindeutige,
ausführbare Folge von Anweisungen endlicher Länge zur Lösung eines Problems.
Was das so im Detail bedeutet, eindeutig ausführbar,
endliche Länge, das sehen Sie hier. Ich möchte jetzt,
also an der Stelle nur auf zwei dieser Eigenschaften eingehen.
Also das ist einmal die Determiniertheit und die Terminierung.
So, Determiniertheit bedeutet, ein Algorithmus würfelt nicht.
Also jedenfalls nicht die Algorithmen, mit denen wir uns typischerweise beschäftigen.
Determiniertheit bedeutet Wiederholbarkeit bei derselben Menge von Eingabewerten liefert einen Algorithmus
immer dasselbe Ergebnis. Und das mag eigentlich selbstverständlich sein,
aber für so eine wissenschaftliche Definition muss das einfach mal festgehalten werden.
Genauso wie der zweite Punkt. Die Terminierung,
ein Algorithmus sollte dann auch mal aufhören. Ein Algorithmus,
der nicht aufhört, dessen Ausführung nicht beendet wird, ist nutzlos.
Und ist deswegen im Sinne dieser Definition auch kein Algorithmus.
Also alle ihre Programme sollten irgendwann aufhören,
sonst sitzen sie irgendwann vor dem Rechner und werden doch verdammt müde,
denken sich,
hört das nochmal auf
Ein Algorithmus, der nicht aufhört, lässt sie da ganz schön lange vorsitzen.
So, und jetzt komme ich zu dem, was ich vorhin so gezeigt habe.
Wir sind ja hier an der Universität Hamburg.
Und ich habe mir das nie genau durchgelesen. Aber ich glaube,
so im Rahmen meiner Lehrverpflichtung, hier bin ich zu weltanschaulicher Neutralität verpflichtet.
Und um das mit Klaus Wovereit zu sagen, das ist auch gut so.
Neutralität bedeutet nicht Gleichgültigkeit. Insbesondere nicht,
wenn man sich so montags dienstags in der Presse anschauen muss,
was für Leute da so mitunter unterwegs sind und irgendwas von Abendenland faseln, Rade brechen.
Also ich unterstelle niemandem Dummheit und auch niemandem Bösartigkeit,
worauf ich nur mal hinweisen wollte,
ist, dass der Begriff des Algorithmus,
der ist abgeleitet von einem Menschen namens, ich kann das,
glaube ich, nicht so aussprechen, wie das gedacht ist,
aber vor allem kann ich das nicht lesen,
so wie das ursprünglich geschrieben worden ist,
aber das ist der Herr Alquaritzmi
Der, seines Zeichens so, irgendwo um diese Zeit hier lebte.
Und der hat also für die arabische Welt,
hat der die Null, also die Null, den Wert Null,
hat der, in deren Zahlensystem aus Indien importiert.
Sodass also auch die Araber zu der Zeit dann mit der Null umgehen konnten.
Was, dann wiederum einen Effekt gehabt hat auf die gesamte abendländische Welt,
die auf einmal auch mit Nullen umgehen konnten.
Was also für das heutige Rechnen doch eine gewisse Rolle spielt,
insbesondere für sie als Informatiker,
wo die Welt eigentlich nur noch als Nullen und Einzelnen besteht
Also ohne den hier gäbe es also das Ganze,
das ist jetzt auch übertrieben. Aber sagen wir mal,
der hat schon eine gewisse Rolle gespielt,
wenn es darum geht, so was wie das,
was sie heute alltäglich machen, nämlich Algorithmen zu definieren.
Also auf denen geht es, das sollte man,
glaube ich, mal mindestens gehört haben,
dass also ein morgenländischer universal gelehrter Mathematiker diesen Begriff des Algorithmus
entscheidend mitgeprägt hat und was der darunter ursprünglich verstanden hat,
war ein genau definiertes Rechenverfahren,
was zu der damaligen Zeit natürlich nicht von Computern
durchgeführt wurde,
sondern von Menschen
So, wenn sie die Definition von Algorithmus,
die ich auf der Vorfolie gezeigt habe, wenn sie sich die nochmal anschauen,
steht da auch extra, dass diese Anweisungsvorschrift von Computern,
Klammer auf, oder Menschen ausgeführt werden können sollte.
So, also die Welt ist bunt und vielfältig und die Quellen,
aus denen wir uns bedienen, aus denen wir schöpfen,
um das zu tun, wofür also sie hier sind,
sind also unendlich und mindestens so, nee,
die sind nicht so unendlich wie die menschliche Dummheit.
Das war sicher einständig sicher,
ob das Universum unendlich ist bei der menschlichen Dummheit,
war er sich sicher.
Zurück zum Thema
Was passiert hier? Manchmal so eine Anweisungsfolge wie das,
was da steht. Das können Sie ja jetzt mittlerweile lesen.
Wie die Gebrauchsanweisungen für Ihren Rasierrepparat. Also es wird eine Variable definiert.
Max. Dass diese Variablen hier nicht deklariert worden sind,
bitte sei so. Also wenn A größer als B ist,
dann wird Max der Wert A zugewiesen.
Ansonsten bekommt Max den Wert B. Ich denke,
das ist intuitiv klar, was diese Anweisungsfolge bedeutet.
Jetzt wollen wir
die verallgemeinern
Deswegen geben wir der einen Namen. Der Name ist sinnvollerweise nicht Minimum,
sondern der ist Maximum. Und dass wir hier deklarieren,
um also diese Allgemeingültigkeit dieser Prozedur zu gewährleisten, so ist.
Wir deklarieren zwei formale Parameter, die als Eingabe für diese Prozedur
dienen können. So, wenn wir das geschafft haben,
dann können wir diese Prozedur Maximum,
dann können wir die aufrufen mit dem,
was also dann im Folgenden auch als aktuelle Parameter in diesem Fall 6 und 9 bezeichnet wird.
Und das gucken wir uns jetzt nochmal bezüglich der Begrifflichkeiten.
Gucken wir uns das nochmal
etwas genauer an
So die Begrifflichkeiten sind insofern hier jetzt, also von Relevanz,
als das so die Unterscheidung zwischen diesen unterschiedlichen Arten von Parametern
für das Verständnis von nicht nur objektorientierten Programmen,
aber überhaupt von dem Typen-Programm in höheren Programmiersprachen notwendig ist.
Zunächst mal, was ist das? Wozu ist das gut, die Parametrisierung?
Sie ist zum Datenaustausch zwischen diesen benannten Anweisungsfolgen und dem Rest eines Programms notwendig.
Ohne die Möglichkeit, Werte in Prozeduren zu übergeben,
gibt es keine, sagen wir mal, nur eingeschränkte und softwaretechnisch,
nicht besonders elegante Möglichkeiten, unterschiedliche Arten von Operationen auszuführen.
Also mit Arten von Operationen meine ich jetzt,
die Anweisung des Folgen, die durchlaufen werden,
sind immer dieselben oder die Möglichkeit, sind immer dieselben,
aber die Werte, mit denen dann diese Anweisungen durchgeführt sind,
werden unterschiedlich sein, eben aufgrund der unterschiedlichen Eingaben,
schrägstrich Parameter, die für diese Prozeduren definiert worden sind.
Sie sehen jetzt hier schon Ein weiteres, einen weiteren Begriff,
nämlich den des Typs. Ich hatte das letzte Woche in der Vorlesung,
hatte ich den Typ ja auch schon so als Wertemenge mit darauf,
definierten Operationen definiert. Auch Parameter haben Typen,
so wie alle Variablen, die wir in getypten Programmiersprachen definieren.
Es gibt keine Variablen ohne Typen. Und das ist etwas,
wir werden darauf später nochmal eingehen, dass es eine Eigenschaft
dieser Art von Programmiersprachen Sie bilden eine bestimmte Typ von Programmiersprachen.
Es gibt andere Typen von Programmiersprachen, in denen das nicht notwendig ist,
warum das unterschieden wird und welche Zwecke,
welche Arten von Programmiersprachen geeignet sind bzw. eingesetzt werden,
werden wir uns auch noch später mal drüber unterhalten.
So für den Moment halten wir einfach mal fest,
dass wenn wir Parameter übergeben, dass die jeweils auch getypt sein müssen.
So, das hatte ich schon angedeutet, dass ich,
also wenn ich über Parameter jetzt im Weiteren spreche,
dass ich zwei Arten von Parametern unterscheiden werde und
das sind die sogenannten Formalen und die aktuellen Eingabeparameter
Dieses Stück Code, von dem können sie sich ja vermutlich vorstellen,
dass sie das einfach so in Java, das ist korrekter Java-Code,
so jedenfalls durch draufschauen, kann ich hier keinen Fehler entdecken.
Das ist korrekter Java-Code, den sie implementieren können.
Wenn sie das tun, dann ist also die Sprechweise,
die Prozedur, die Methode Maximum verlangt zwei formale Parameter.
Diese beiden formalen Parameter haben den Namen,
den Bezeichner A bzw. B sind vom Typ Int, also Intiger.
Mit diesen beiden Größen, A und B, kann jetzt innerhalb der Operation,
die diese beiden formalen Parameter besitzt, kann innerhalb dieser Operation gearbeitet werden.
Wenn ich diese formalen Parameter für die Definition der Prozedur verwende,
dann muss ich die auch an der aufrufenden Stelle,
sie sehen jetzt hier zwei Beispiele für den Aufruf dieser Operation,
Maximum, dann muss ich die auch verwenden.
Und was jetzt passiert im Programm Ablauf,
Ist es die aktuelle Parameter, das hier sind nämlich die aktuellen Parameter,
also diese beiden jeweils Ergebnisse ist der erste aktuelle Parameter zweimal X, ist der zweite aktuelle Parameter.
Die Werte dieser beiden Parameter werden beim Aufruf an die formalen Parameter gebunden. Das ist in dem Beispiel,
in dem ersten aufrufenden Beispiel, sind es halt Literale,
Zahlen, die hier als aktuelle Parameter übergeben werden,
hier ist es jetzt was anderes, nämlich ihr wird der Wert einer Variablen,
wird hier als Parameter übergeben und hier wird ein Ausdruck als aktueller Parameter übergeben,
was zunächst mal die Frage, also eröffnet,
wann wird denn dieser Ausdruck eigentlich ausgewertet?
Welchen Wert soll also zweimal X ergeben, mal ganz abgesehen davon,
dass also sie diesen Ausdruck jetzt nicht auswerten können,
weil unklar ist, also welchen Wert X haben könnte?
Die Antwort darauf ist, bevor der Kontrollfluss in die Operation Maximum übergeht,
werden die aktuellen Parameter ausgewertet, das heißt das Ergebnis dieser Ausdrücke wird berechnet
Und erst dann wird in den eigentlichen,
in die eigentliche Anweisungsfolge der Operation hier in diesem Fall Maximum verzweigt.
Das heißt also, hier braucht jetzt nichts ausgerechnet werden,
ausgewertet werden, weil das ist schon ein Wert,
die der Wert der Variablen Ergebnis wird an den formalen Parameter A gebunden,
schrägstrich zugewiesen und das Ergebnis des Ausdrucks zweimal X wird an den Parameter,
an den formalen Parameter B zugewiesen
Das heißt, das Verhältnis ist also immer eins zu eins,
das kann man sich hoffentlich auch einfach erklären.
Man wird von der Stelligkeit, Herr, ist es eindeutig,
dieser aktuelle Parameter wird an der ersten Stelle steht,
wird an diesen formalen Parameter gebunden und dieser aktuelle Parameter wird an diesen formalen Parameter gebunden.
Allgemein ist es dann, kann man diese Regeln bei der Parameterübergabe
Kann man sich jetzt so vorstellen, so wenn eine Prozedur in einem Programm,
in einem objektorientierten Programm aufgerufen wird, dann ist das ja zunächst etwas,
was sie statisch in ihrem Quelltext niedergeschrieben haben.
Das ist das Erste, was so ein Compiler dann tut,
also das tut er nicht wirklich, aber so das,
was man sich so im Moment modellhaft vorstellen kann, was der tut,
ist, sie rufen also an einer Stelle eine Operation,
eine Prozedur namens Maximum auf.
Und zunächst mal wird geschaut, da gibt es
diese Operation denn überhaupt
Also der Name Maximum ist der bekannt. Okay,
jetzt nehmen wir mal an, das sei so,
sie haben sich nicht vertippt und irgendwo gibt es eine Operation.
Maximum, dann wird geschaut, nun, die Anzahl der aktuellen Parameter beim Aufruf,
ist die denn gleich der Anzahl der formalen Parameter?
Das heißt, in unserem Fall sind da auch jeweils zwei Parameter.
Wenn man da einen Haken dran machen kann,
dann werden also die, dann wird noch geschaut, ob die Parameter,
die dort übergeben werden, ob die Typ kompatibel sind,
für den Moment können wir Typ Kompatibilität so definieren,
Wir müssen vom selben Typ sein.
Also wenn ein Intager erwartet wird, als formaler Parameter,
dann müssen sie auch als aktuellen Parameter einen Intager übergeben.
Wenn eine dieser Regeln verletzt ist, dann wird dieses Programm nicht übersetzt.
Sie kriegen es überhaupt gar nicht erst zur Ausführung.
Das ist ein Kennzeichen, dieser statisch und stark getypten Programmiersprachen.
Sie können keine Programme übersetzen, die Typfehler enthalten. Wenn
Sie jetzt hier als aktuellen Parameter meinetwegen den An dieser Stelle den String-Ergebnis,
die Zeichenkette-Ergebnis, also eingekreist in Hochkombatar übergeben würden,
dann würde der Compiler irgendwie sagen, nein, daraus mache ich kein übersetztes und ausführbares Programm.
Geht nicht. Diese starke Reglementierung schützt sie davor,
pro Probleme zur Laufzeit eines Programms zu bekommen, die sie nicht haben wollen.
Sie wollen nämlich nicht,
dass also einmal der String-Ergebnis dort als Parameter übergeben wird und
zur Laufzeit des Programms dann ein Effekt eintritt, der da heißt,
ich kann mit dem Stringergebnis keine kleiner, gleich Operation durchführen.
Es geht einfach nicht, beziehungsweise es ergibt keinen Sinn.
Es gibt andere Programmiersprachen, schwachgetypte Programmiersprachen, die lassen das zu.
Der Grund dafür, dass es diese Sprachen gibt, ist,
nur man kann sehr viel schneller Effekte erzielen, die man haben will,
wenn man weiß, wie man diese Sprachen zu bedienen hat.
Für langfristige, stabile Softwareentwicklung hat sich,
soweit wie ich das einschätzen kann,
haben sie stark getypte Programmiersprachen durchgesetzt,
einfach weil sie ein höheres Level an Sicherheit bei der Programmausführung
mit sich bringen
So, jetzt habe ich schon über Parameterübergabe und wie kommt es also in diese Operation rein?
Wie habe ich das, das habe ich schon besprochen,
worüber ich noch nicht gesprochen habe, ist,
wie kommt das Ergebnis, das also bei einer,
bei der Durchführung einer Folge von Operationen wie hier bei Maxikum,
Maximum, wie kommt es eigentlich wieder raus aus dieser definierenden Stelle,
aus dieser Operation Maximum.
Und jetzt gucken wir uns die erste Zeile dieser Prozedurdefinition,
die gucken wir uns jetzt nochmal kurz genauer an.
Also bis jetzt habe ich über diesen Teil hier gesprochen,
also der Name und die beiden formalen Parameter Integer A und Integer B.
Worüber ich noch nicht gesprochen habe, ist dieses Schlüsselwort,
das hier vorne steht. Und dieses Schlüsselwort gibt in den,
in vielen Programmiersprachen unter anderem dann eben auch in Java,
gibt es an, von welchem Typ ist der Wert,
den diese benannte Folge von Anweisungen zurückgibt. Und die Aussage,
die sie hier treffen, wenn sie das so hinschreiben,
ist, ich verspreche, Also in dem Moment,
wo ich das so hier hingeschrieben habe, ich programmiere,
verspreche, dass die Operation Maximum einen Wert vom Typ Integer zurückliefert.
Das kann auch ein Compiler überprüfen, ob sie dieses Versprechen einhalten,
denn sie müssen so an der einen oder anderen Stelle Details,
dazu wird Fred dann noch Stellung nehmen.
Sie müssen an der einen oder anderen Stelle müssen sie ein Schlüsselwort verwenden.
Und dieses Schlüsselwort heißt Return. Und das ist für den Compiler
das Zeichen, aha, Hinter kommt jetzt ein Wert,
den soll ich zurückliefern als letzte auszuführende Anweisung in einer Operation.
Und der muss von dem Typ sein,
der hier oben in der Prozedur Definition versprochen worden ist.
So, jetzt kann man nur hoffen, also da braucht man nicht zu hoffen.
Da braucht man auch nicht beten. Das kann man ablesen.
Hier ist eine lokale Variable Max definiert worden vom Typ Integer.
Und die wird an dieser Stelle returniert, zurückgegeben.
Und damit ist der Compiler dann erstmal zufrieden, natürlich nicht überprüfen kann,
ist, ist, ob ihre Operation korrekt ist.
Also im Sinne, ob sie wirklich das Maximum hier zurückgeben,
der Compiler überprüft das syntaktisch und sagt, ja,
das kann ich durchgehen lassen, weil,
also es ist ein Integer als Rückgabewert versprochen und dieser Integer wird mit dieser Anweisung dann auch zurückgegeben.
So, jetzt können wir nämlich,
jetzt können wir uns auch erklären, warum,
also diese Stelle hier, also nicht in Compiler dazu bringt,
zu sagen,
einen Moment mal,
wieso wird denn hier an einen Integer
etwas zugewiesen
Für diese benannte Aufrufreihenfolge. Warum kann, also warum ist
das legitim? Warum ist das syntaktisch korrekt? Nun ja,
diese Operation liefert einen Intiger und ich kann einen Integer an
den Wert eines Integers, an den Wert eines anderen Integers zuweisen.
So, und das hier ist jetzt kein Wert eines Integers,
sondern die Folge des Ausführens dieser Operationsreihenfolge ist,
dass ein Integer-Wert geliefert wird und den kann ich an die variable Ergebnis beziehungsweise an die variable Ergebnis 2 zuweisen.
Das ist so, es ist eigentlich Ist eigentlich schon so,
das ist ja kein Geheimnis,
also so kann man sich den Kontrollfluss erklären und sie sehen das jetzt hier auch nochmal versucht,
in geraden deutschen Sätzen, also das aufzuschreiben,
was ich Ihnen gerade versucht habe zu erklären, so ein Punkt,
auf den ich also bewusst nicht weiter eingegangen bin,
den sie aber auch in ihrem weiteren Studium noch so kennenlernen werden.
Alles, womit wir uns hier im Rahmen von SE1 und SE2
beschäftigen werden, sind sequenzielle,
imperative Programme
Wir beschäftigen uns nicht mit dem Thema Nebenläufigkeit.
Jetzt sage ich Ihnen etwas, wovon Sie noch nicht,
gehe ich jedenfalls, gehe ich jedenfalls davon aus,
ich sage Ihnen jetzt etwas, wovon Sie noch nicht wissen,
dass Sie es nicht wissen.
Also es ist unbekanntes Unwissen, dass da jetzt,
das ist ungefähr so gut wie Dummheit.
Also zu Ihrem Unbekannten Unwissen, jetzt Abgleich nicht mehr,
gehört, dass es Programme auch parallel nebenläufig ausgeführt werden können.
Sie nutzen das, so könnt ihr jetzt mal fragen,
wer von Ihnen benutzt,
Spielekonsolen in seiner Freizeit
Ja. Wie, ich nicht? Ich nicht. Nicht mein Leben.
So. Die könnten gar nicht funktionieren, wenn nicht diese Prozess,
also die Prozessoren, die dort drin verbaut worden sind,
nicht über eine Reihe von Prozessoren verfügen würden, die Befehle,
die dort angefordert worden sind, auch parallel ausführen können.
Das zu programmieren übersteigt das, womit wir uns hier
in SE1 und SE2 beschäftigen können.
Also wir beschäftigen uns ausschließlich mit sequenziellen Imperativen Sprachen
Diese höherwertigen Konzepte, mit denen man dann lustige Sachen implementieren
kann, das machen wir später. So,
jetzt ist es nicht mehr unbekanntes Unwissen, sondern jetzt,
und das ist schon viel besser, jetzt haben Sie bekanntes Unwissen.
Ich weiß, dass ich etwas nicht weiß. Und das
Ziel dieser Vorlesung ist es, Ihr bekanntes Unwissen zu vergrößern.
Nicht zu vergessen, das bekannte Wissen auch zu vergrößern.
So, ein Punkt, der hier noch drinsteht,
auf den ich bis jetzt auch noch nicht zu sprechen gekommen bin,
Prozeduren können geschachtelt aufgerufen werden,
Was will er uns damit sagen? Schauen wir uns
noch mal kurz den Code von Maximum an.
Wie kann man da an drei Zeilen Code die Welt erklären?
Da sind keine weiteren Prozeduraufrufe drin enthalten, oder?
Nein, das ist kein Prozeduraufruf. Das ist auch eine
einfache Zuweisung. Das weiß man nicht, was das ist.
Aber wenn jetzt meinetwegen hier an dieser Stelle noch ein Prozeduraufruf stünde,
dann wäre das ein geschachtelter Prozeduraufruf,
weil innerhalb der Abarbeitung von Maximum, dann nochmal eine andere,
ich sage jetzt erstmal andere, muss nicht sein,
aber für den Moment eine andere benannte Folge von Anweisungen aufgerufen wird.
So, das ist mit Schachtelung gemeint. Und das kann also nicht unendlich tief,
aber das kann beliebig tief werden, warum auch nicht,
also wenn hier jetzt für die Verarbeitung, also der Grund dafür,
dass man sich die Operation Maximum definiert hat, war ja,
okay, das kann man an vielen verschiedenen Stellen zu unterschiedlichen Zwecken,
kann man das gebrauchen,
also definiere ich mir mal Maximum
Ich kann es ja innerhalb von Maximum, kannst also noch Anweisungsreihen
folgen gehen, die ich auch mal da rausnehmen möchte.
Das ist ja das Spiel des Fred, so gerne mit ihnen,
spielt, hey, hier steht dreimal hintereinander, fünf Zeilen lang derselbe Code.
Was kann ich tun? Ich faktorisiere das raus,
dann brauche ich es nur noch einmal hinschreiben.
Schon ist der Code kürzer. Genau dieses Spiel,
also ein Spiel in Anführungsstrichen, also wird häufiger durchgeführt und
dann spricht man von geschachtelten Aufrufen und da gibt es keine prinzipiellen Beschränkungen.
Das macht man halt, also in dem Moment,
wo einem auffällt, also entweder hier gibt es,
komplizierten Code, das will man sowieso immer vermeiden,
dann faktorisiere ich das raus in eine eigene Prozedur.
Oder wenn man feststellt, ich brauche hier eine Folge von Anweisungen,
die von verschiedenen Stellen aus aufrufbar sein soll, zack,
wird das rausfaktorisiert und man hat geschachtelte Aufrufe. So,
der Punkt für uns ist dann aber,
egal ob diese Aufrufe jetzt geschachtelt sind oder nicht,
der Kontrollfluss in einem sequenziellen,
emperativen Programm geht von der Aufrufstelle an die aufgerufene Prozedur,
aufgerufene Prozedur wird abgearbeitet, mit geschachtelten Aufrufen oder nicht,
und kehrt dann hinter die Stelle zurück, an der sie aufgerufen worden ist.
So ist das Verarbeitungsmodell in sequenziellen, emperativen Programmiersprachen. So,
jetzt haben Sie schon so zwei verschiedene Programmiersprachen kennengelernt,
nämlich einmal Carol als eine imperative Programmiersprache,
also eine Programmiersprache in der wesentlichen Zuweisung,
möglich sind und Zuweisungen sind eine Art von Anweisungen,
die in der Sequenz durch Fallunterscheidung oder durch Wiederholung strukturiert, können.
Und sie haben eine andere Art von Programmiersprache kennengelernt.
Das sind die, ist eine objektorientierte Programmiersprache in unserem Fall Java.
Das ist jetzt so von der Begrifflichkeit. Ich habe jetzt im Wesentlichen,
nicht nur im Wesentlichen, ich habe versucht, den Begriff der Methode zu vermeiden.
Ich habe immer von Prozeduren als den benannten Anweisungsfolgen gesprochen.
In objektorientierten Programmiersprachen spricht man also anstelle von Prozeduren auch von Methoden.
Der erste Teil dieser Folie sagt, was ist zwischen Prozeduren und Methoden gemeinsam?
Dann sehen Sie schon, dass wovon ich jetzt gerade gesprochen habe,
benannte Anweisungsvollen, wechselt des Kontrollflusses, es können Parameter übergeben werden. So,
jetzt gucken wir nochmal, vor eurem geistigen Auge hoffe ich,
haben Sie jetzt noch so das ein oder andere Carrat-Programm,
das Sie geschrieben haben und aktuell das eine oder andere Java-Programm,
so die Carrat-Operation, die Carrat-Prozeduren,
die konnten Sie in Anführungsstrichen freifliegend aufrufen.
Sie haben die aufgerufen, der Kontrollfluss wechselte,
der Kontrollfluss kam zurück und das war's dann.
Für die objektorientierten Programmiersprachen ist es ein bisschen anders,
es ist eingeschränkt, Sie können eine Objektorientierung in einer objektorientierten Programmiersprache,
können Sie eine Operation immer nur an einem Objekt aufrufen
Sie können nicht einfach die Operation Maximum aufrufen,
sondern es gehört also immer zu einer Operation, zu einer Methode,
gehört das Objekt, an dem diese Methode aufgerufen wird.
Das hört sich jetzt erstmal an wie eine Einschränkung,
ist aber durchaus sinnvoll, weil damit immer klar ist,
zu welchem Kontext gehört die Operation eigentlich, die gerade aufgerufen wird.
Das diszipliniert sie in einer gewissen Art und Weise,
nämlich in der sie sagen, nun,
wenn ich jetzt sowas wie die Klasse Konto,
die Klasse Kunde irgendwas von der Art und Weise schreibe.
Dann ist diese Klassendefinition ja dadurch geprägt, dass sie definieren,
was sind die öffentlich sichtbaren Elemente der Schnittstelle?
Ich könnte doch das öffentlich auch streichen, weil oh,
Schnittstelle ist immer öffentlich. Was sind die Elemente dieser Schnittstelle?
Und dann ist auch klar, dass sich jede der Methoden,
die Teil dieser Schnittstelle sind, immer auf das Objekt beziehen,
das gerade erzeugt worden ist von dieser Klasse.
Und das gibt ihnen, also den Halt zu wissen,
welche Effekte können auch,
also mit einer solchen Operation,
mit einer solchen Methode erzielt werden
Weil so eine Methode kann immer zugreifen, jetzt ist es
sowohl nur, als auch auf alle Felder des zugehörigen Objektes.
Also das, was in einer Klassendefinition als Zustandsvariablen als Felder
für diese Klasse definiert worden ist. Und das gucken wir
uns jetzt nochmal an dieser benannten oder bereits benannten Klasse Girokonto an.
Das hier können Sie, glaube ich, mittlerweile auch lesen.
Jetzt gucken wir uns mal an, welche Arten von Variablen
in dieser Klasse eigentlich definiert worden sind.
Und wir haben jetzt also schon Arten von Variablen kennengelernt.
So, zunächst mal sind es die Expectenten, was jetzt
nur in der Reihenfolge, in der sie hier auftauchen.
Zunächst mal sind es die sogenannten Exemplar-Variablen. Was sind Exemplar-Variablen
? Das sind die Variablen, die Bestandteil des Zustandsraumes,
die den Zustandsraum eines jeden Objektes dieser Klasse bilden.
Jedes Objekt der Klasse Girokonto verfügt über eine private Integer-Variable Saldo. Die kann natürlich,
natürlich für jedes Objekt der Klasse Girokonto einen unterschiedlichen Wert haben,
bloß wovon sie ausgehen können, ist,
wenn es ein Objekt der Klasse Girokonto gibt,
dann hat dieses Objekt auch eine Exemplarvariable namens Saldo vom Typ Integer.
So, an diesen Exemplarvariablen, die für alle Methoden der Klasse Girokonto sichtbar sind,
kann der Zustand von Objekten dieser Klasse gehalten werden.
Die zweite Art von Variablen, die wir jetzt kennengelernt haben,
das sind die formalen Parameter,
Die Sichtbarkeit dieser formalen Parameter ist begrenzt auf die Methoden,
für die dieser formale Parameter definiert worden ist.
Also sie können auf die Variable Betrag, können sie
nur innerhalb der Anweisungsfolgen der Operation der Methode einzahlen, zugreifen.
Sondern es passiert ja hier auch. Und zwar passiert das
auch unter Verwendung der lokalen Variable neuer Saldo. Eine lokale Variable,
der Name legt es auch schon nahe,
ist nur sichtbar innerhalb der Anweisungsfolge einer Methode,
nämlich der Methode innerhalb der, diese lokalen alle Variablen definiert worden ist.
Während also auf die Exemplarvariable Saldo innerhalb der Operation Einzahlen zugegriffen werden kann,
kann auf die Variable neuer Saldo,
das hat ja so eine Art Zwischenergebnis, so eine Art Zwischenergebnis,
da kann, auf die kann nur innerhalb der Operation innerhalb der Methode Einzahlen zurückgegriffen werden.
So, das sind so die,
und ich verspreche ihnen hiermit mehr Arten von Variablen gibt es nicht,
jedenfalls nicht so in der Programmiersprache Java, diese den Gebrauch,
den Umgang mit diesen drei Arten von Variablen,
werden sie kennenlernen und irgendwann ist das für sie genauso natürlich wie Naseputzen,
also mit diesen drei Arten von Variablen umgehen zu können.
So, damit bin ich dann auch schon bei einem Zwischenergebnis angekommen und sie können sich das hier anschauen,
während ich in Kommunikation mit Fred trete,
ob ich noch was über die Virtual Machine erzählen soll oder ob du schon gleich Fred schüttelt den Kopf,
Fred kommt und wird Ihnen das jetzt live und direkt,
was ich jetzt hier mit dem Mund erklärt habe,
wird er Ihnen vorführen und dann kann ich das tun,
was ich Mittwoch nachmittags unglaublich gerne tue,
Ihnen ein schönes Wochenende wünschen.
So, das ist ja alles schon, das lösche ich
mal alles wieder.
Weg damit
Das löschen wir auch mal. Sehr schön. Ja,
genau wie Guido quasi zwei Teile in seiner Vorlesung hat er
erst ein bisschen imperative Grundlagen, dann so ein bisschen was über Oro.
Wollte ich das heute eigentlich auch machen. Ich hatte erst ein bisschen überlegt,
ob ich vielleicht sogar eine andere Sprache für den ersten Teilnehmer dachte,
nee, Kerl und Java, das reicht,
ich muss hier nicht noch was Drittes machen.
Okay, naja, wir standen mal imperativ,
da fällt gerade nichts Besseres an.
Und ich wollte jetzt mal mit euch ein oder zwei Prozeduren programmieren.
Also in Java gibt es ja nur Methoden,
wir werden dann jetzt einfach mal ignorieren,
dass Methoden auch auf Zustandsfelder zugreifen dürfen
Ja, okay. Es gibt aber so ein paar ganz nette Beispiele für Methoden,
die nicht so trivial sind, dass sie einen langweilen.
Was ich zum Beispiel immer unheimlich gerne mache, ist Wurzel ziehen.
Das hatte ich letztes Jahr erstmal demonstriert. Das ist dann
in Java auch was eingebautes. Es gibt hier unten so
eine wunderbare Direkteingabe, die kann man mit Steuerung eh aktivieren.
Oder wenn ihr nicht Windows oder Linux benutzt, ist es
manchmal auch ein anderer Schalker, das sieht ihr hier.
Hier unten kann man einfach so diverse Dinge eingeben. Okay,
und man kann zum Beispiel in Java,
wenn man da Wurzel ziehen will, gibt es da für eine Operation,
die heißt SQRT, die rufen an einem Mars-Objekt auf.
Und dann kann ich zum Beispiel sagen,
was ist denn die Wurzel von 81?
Und dann kommt da neu raus
Okay. Und wir tun jetzt mal so, als würde es
diese Funktion nicht geben und wir würden trotzdem Wurzel ziehen wollen.
Ich hatte dazu mal in meinem Kopf ein Bild,
das ich euch gerne zeigen würde, aber jetzt sehe ich gerade,
da gibt es ja nicht irgendwo GIMP, GIMP starten,
Bild, Editor, ich hoffe mal, das ist dasselbe.
Ja, genau. Es gibt so ein schönes,
nettes Verfahren zum Wurzelziehen, so ein schöner Algorithmus,
das Thema war heute auch ein bisschen Algorithmusbegriff.
Ach, macht das Spaß auf so einem alten Laptop
mit so einer niedrigen Auflösung?
Ich versuche mal hier
irgendwas Sinnvolles hinzubekommen
Also, machen wir doch mal ein neues Bild. Tja,
ich hoffe mal, dass das sinnvoll ist, passt das drauf.
Ja, ich hätte wahrscheinlich auch ein bisschen größer nehmen können.
Ich versuche mal ein bisschen größer, versuchen wir mal 800 nach 600.
Und dann mal eins zu eins. So. Okay,
wenn man in Deutschland Wurzel sagt, meint man ja immer die Quadratwurzel.
Und wen wundert es, Quadratwurzeln haben was mit Quadraten
zu tun? Ich versuche jetzt mal ein Quadrat zu zeichnen
Okay, also ihr glaubt mir hoffentlich, dass das ein Quadrat ist.
Und dieses Quadrat hat die Fläche X. Wie lang ist dann die Seite?
Neuer Wurzel von X, ne? Die Fläche eines Quadrats ist ja,
oder allgemein von Rechtecken ist ja die eine Länge mal die andere,
oder die Höhe mal die Breite oder so.
Das heißt, wenn ich die Fläche dieses,
wenn die Fläche zum Beispiel 81 ist, dann wird die Länge hier neun sein.
Okay, aber nehmen wir an,
wir wissen das gar nicht, dass die Länge neun ist,
dann könnten wir einfach mal irgendeinen Wert raten.
Ich mache jetzt nochmal ein neues Bild,
das ist hier nicht zu groß von anders
Ich rate jetzt einfach mal, dass die Wurzel von X
zum Beispiel, sagen wir mal, vielleicht so lang ist.
Und das ist viel zu kurz. Ja, okay.
Ich will aber trotzdem die Fläche X insgesamt haben. Ich mache euch das mal weniger abstrakt,
nehmen wir vielleicht mal die Fläche 100. Ja,
und nehmen wir mal an, ich habe geschätzt,
dass die Wurzel von 100, wie ist hier so das Verhältnis,
sagen wir mal, vielleicht 8, 5,
5. Also ich habe vermutet, dass die Wurzel 5 ist,
das ist so eine Art Schätzwert von mir.
Und jetzt könnte ich aber rechnen,
wie lang ist denn jetzt dann diese andere Seite?
Also diese Seite ist 5, die Fläche ist 100,
wie lang ist jetzt die andere Seite,
Mathematik an die Front
20. Ich habe einfach 100 durch 5 geteilt. Okay.
Jetzt ist 5 sicherlich zu kurz, 20 sicherlich zu lang.
Was macht man jetzt? Ich habe irgendwie zwei Werte,
der eine ist zu klein, der andere ist zu groß.
Mittelwert, genau. Ich könnte also einfach sagen,
hey, nehmt doch die 20, plus die 5,
ich hätte vielleicht mal den Stift ein bisschen dünner machen sollen.
Und Teile ist auch einfach mal durch zwei. Und dann kommt
ein Wert raus, der ein bisschen näher dran ist.
Und dann spiele ich das Spiel weiter und das kann man
wunderbar programmieren. Okay, sieht aus wie ein Geldschein,
oder? Juhu, 100 Euro, ich bin reich.
Gut, dann schließen wir das mal wieder
Nur so als Grundidee, dass ihr nicht völlig gleich denkt,
hä, was programmiert Fred hinter?
Da verstehe ich ja überhaupt nicht das Prinzip dahinter.
Wie viel Fenster habe ich denn hier?
So. Gut. Wir könnten erst mal einfach anfangen unter Prozedur
schreiben, die mir einen Mittelwert berechnet.
Das werde ich ja brauchen für die Wurzelberechnung.
Und wir versuchen uns jetzt noch mal zu erinnern,
wie sah denn das ganz allgemein aus, wenn ich eine Prozedur definieren will?
Also ich muss erst mal den Ergebnis-Typ dahin schreiben.
Oder man sieht es auch mal mit einer Rückgabetyp.
Okay, dann muss der Name der Funktion kommen.
Und dann kommt in runden Klammern die Liste der formalen Parameter.
Ich nenne das jetzt mal formaler Parameter-Typ 1, formaler Karamid,
Typ 2. Und jetzt kürze ich das mal ab.
Also theoretisch könnte ich dann noch mehr, ohne Entschuldigung,
völliger Quatsch. Name 1, so ist das, oder?
Ich muss erst den Typen und dann den Namen angeben und
dann könnte ich noch weitere Parameter dahinter schreiben,
aber dann würdest du es hier nicht mehr auf dem Bildschirm passen.
Also ich stand da im Prinzip beliebig viele Parameter reinstecken.
Okay, wie wollen wir die Funktion nennen,
irgendwie so ein schönes englisches, griffiges Wort,
was den Durchschnitt berechnet von zwei Werten?
Was heißt Durchschnitt auf Englisch? Average? Wollen Sie
Average nennen
Okay, wie viele Parameter sollen denn da rein?
Also wenn ich zum Beispiel von 5 und von 20
den Mittelwert bestimmen will, wie viele Parameter sind das?
25? Ziemlich lange Parameterliste, oder? Ja.
Zwei Stück. Also ich brauche auf jeden Fall zwei.
Was ist denn der Typ des ersten Formatparameters?
Also da werden ja sicherlich später auch irgendwelche Komma-Zahlen entstehen,
mit denen ich umgehen muss. Ja, da wird.
Genau, wir wollen möglichst gute Präzision haben,
ungefähr 16 Stellen hinterm Komma. Ja gut,
in der Mathematik ist man jetzt immer nicht so kreativ,
was die Namen angeht.
Ich nenne das einfach mal
Ah, okay. Und dann nenne ich
den zweiten Parameter einfach mal B. Gut. Okay,
also ich stecke es jetzt mal als Beispiel und angenommen,
A, hätte den Wert 5. B, hätte den Wert 20,
dann würde da irgendwie rauskommen, so 12,5 oder so.
Was ist dann also ein sinnvoller Ergebnistyp? In oder String
? Ja. Auch dabei, genau. Also ich tue
zwei Doubles rein. Das sagt quasi dieser Abschnitt des Codes,
du musst zwei Doubles reinstecken.
Und dieses Double sagt, ich liefere dir einen Double zurück.
Das Ergebnis ist auch ein Double
Okay, jetzt mache ich das mal recht ausführlich.
Also ich hatte ja schon gesagt, ich muss das irgendwie erst mal aufaddieren.
Also ich könnte zum Beispiel sagen, die Summe ist A plus B.
Nur habe ich schon mal die Summe gebildet. Okay,
da muss ich das sicherlich irgendwie halbieren,
da könnte ich jetzt irgendwie sagen, vielleicht schauen wir das mit V,
wenn es Singular ist oder so.
Nee, so, ne? Wäre da zum Beispiel Summe
durch zwei. Und da habe ich es auch schon geschafft,
dann kann ich die Hälfte zurückgeben.
Ich habe das jetzt so ein bisschen ausführlich gemacht,
das wird da gleich schön durchsteppen können und so ein bisschen die Zwischenergebnisse sehen können.
Okay, aber ich glaube, wir sind auch schon fertig.
Ich mache immer so ein paar Leerzahlen,
dass man es ein bisschen besser optisch sieht
Okay, und jetzt kommt aber die größte Herausforderung für mich,
wie ordne ich das jetzt so ein Blu-Jay an,
dass man irgendwie gleichzeitig den Code sieht und den Debugger?
Also, dann tue ich doch mal hier einen Haltepunkt hin.
Nee, warte mal, ich muss das ja hier unten aufrufen.
Wenn ich das hier unten aufrufe, verschwindet das wieder.
Das heißt, ich muss das jetzt auch erstmal kleiner machen.
Machen wir das vielleicht mal. Sorry irgendwie. Ach,
das wird wieder lustig werden. So. Okay. Warum erscheint
jetzt diese Prozedur Average nicht, wenn ich auf die Klasse
raufklicke?
Wiederholungsfrage von letzter Woche quasi
Ich habe sie doch gerade geschrieben, wo ist sie denn?
Ja. Wir müssen erst mal noch Black erzeugen, ne?
Genau, also in Java muss sich diese Objekte erst mehr erzeugen.
Gut, nenne ich es einfach mal.
Ist ja eigentlich egal, wie ich es nenne.
Ich nenne es weh, mir fällt gerade nichts Besseres ein.
Ist aber völlig egal. Das hat jetzt keinen Einfluss auf das,
was jetzt kommt. Und jetzt kann ich hier sagen,
ich möchte diese Average-Methode aufrufen. Okay, also nochmal als Wiederholung
, ich muss ein Double, noch ein Double reinstecken.
Und dann rattert dieser Algorithmus durch, der ein bisschen addiert
und dividiert. Und dann kommt ein anderer doppelt zurück.
Welchen Effekt hat das in Blue J.
Wenn ich an eine Methode aufrufe, wird die Parameter erwartet.
Ja. Fruchtgerutscht mit welcher Typ das ist,
dass er so lernt, wo das jetzt passiert.
Genau, sehr schön. Ein sehr schöner grafischer Prompt öffnet
sich jetzt, weil ich muss ja sagen,
welche Werte sollen A und B denn jetzt haben?
Das kann er ja nicht wissen, kann ja nicht Gedanken lesen.
Da haben wir es sehr schön. Du hast auch schon gesagt,
man sieht ja auch die Typen, toll,
kann man also eigentlich fast nichts mehr falsch machen.
Ja, dann nehmen wir mal das Beispiel von eben,
also zum Beispiel die 5 und die 20.
Und was wird jetzt passieren, wenn ich okay klicke?
Ich habe noch jemand anders
Ganz pinkelig ist Data Assistent. Ah, stimmt. Wir haben ja gesagt,
wir haben ja gesagt, zunächst müssen die Typen gleich sein.
Das heißt, man könnte jetzt vermuten,
dass er sagt, das ist ja gar kein Double.
Aber zum Glück ist Java so, ich sag mal,
benutzerfreundlich, dass er sagt, na gut,
dann wandle ich das innen Double um für dich.
Brauchst du nicht selber Kommando. Also eigentlich könnte man jetzt
hier noch schreiben, 5,0 oder so,
aber das braucht man nicht unbedingt in Java.
Ja, was wird passieren, wenn jetzt okay klicken?
Kriege ich irgendwie eine Mail mit dem Ergebnis oder?
Meldet sich,
da meldet sich ein
Oh, stimmt, ich habe den Haltepunkt ganz vergessen.
Sehr gut, ja, richtig. Wir landen jetzt erst
mal in der Prozedur drin. Guck mal, das hatte ich
schon wieder ganz vergessen, dass ich diesen Haltepunkt gesetzt habe.
Okay. Was schon mal sehr spannend ist, man sieht jetzt
hier tatsächlich die konkreten Werte von A und B. Dadurch,
dass ich den aktuellen Parameter 5 und den aktuellen Parameter 20 reingesteckt habe,
hat jetzt der formale Parameter, der formale Parameter A,
den Wert 5 und der formale Parameter B, hatten wir 20.
Und das ist eine Eigenschaft von BlueJay oder eine Eigenheit,
dass die formalen Parameter hier auch unter lokale Variablen geführt werden.
Warum? Fallformale Parameter genauso wie lokale Variablen,
nur innerhalb der Methode existieren
Okay, aber es wäre auch genauso denkbar gewesen,
dass da eine eigene Überschrift für Parameter gewesen wäre.
Okay, das ist also schon mal ziemlich spannend, die Information,
die ich reingesteckt habe, sehe ich jetzt hier tatsächlich.
A und B haben diese konkreten Werte. Okay,
und wenn ich jetzt ein Step mache, sieht man,
jetzt ist eine weitere lokale Variable hinzugekommen.
Diese, er hat ja hier gesagt, ich will
diese lokale Variable anlegen und welchen Strafwert soll sie haben?
Bitte idiere doch A und B, also hat er 25 Addierten,
hatte ich 25 da reingesteckt.
Okay, dann kommt noch eine lokale Berape, wie sehe ich die jetzt?
Ach, hier fangen schon Strollbargen an, kann ich das
irgendwie größer ziehen?
Da seht ihr, da hat er einfach ausgerechnet, okay,
in Summe steht 25 drin, was ist 25 durch zwei?
Das ist ja sicherlich 12,5, dann stecke ich da mal
12,5 Fragen. So, und jetzt kommt die Frage,
die ich eigentlich stellen würde.
Was passiert denn jetzt, wenn ich dieses Return ausführe?
Was heißt Return? Ja. So schön heißt das,
der Governance zu bleiben, als der Wert der Methode zu bleiben.
Okay, also der wird als Wert der Methode
zurückgegeben und wie macht sich das im Bluejay bemerkbar
Möglicherweise könnt ihr das gar nicht wissen, weil alle Methoden,
die ihr bis jetzt in Blu-ray aufgerufen habt,
immer nur Void zurückgegeben haben.
Dann werdet ihr jetzt sozusagen live in Jungfern von mir verlaufen der Kamera, Achtung.
Aha, seht ihr das? Euer erstes Methodenergebnis, live in Blu-ray.
Man sieht also, es ploppt hier so ein Fenster auf.
Und man sieht auch nochmal wunderbar den ganzen Aufruf. Also,
wenn ich auf dem Objekt W,
die Methode Average aufrufe und ich übergebe die 5 und die 20,
dann wird zurückgegeben ein Double, nämlich 12,5. Nicht schlecht, oder?
Und wenn ihr diese grafische Anzeige irgendwie nicht so toll findet,
Dann nehme ich mal diesen Haltepunkt kurz weg.
Dann könnt ihr das auch hier in diese Direkteingabe eingeben.
Also ihr könnt hier eingeben, w.everage 5,20. Und
dann sagt ihr euch, was das Ergebnis ist.
Das ist auch irgendwie ganz nett. Dann kann ich nicht ausversehen
das Fenster wegklicken oder irgendwas. Jetzt sieht man es hier
für alle Zeiten, bis sich Bluedray irgendwann mal schließe.
Okay. Habt ihr zu dem Average erst mal noch Fragen?
Ich tue 2 Double 2, ich berechne einen Mittelwert.
Wer weiß nicht, wer war da erst zu teilen,
weil wenn dann die Nummer zu bilden war, solltest du brauchst.
Du willst erst teilen und dann die Summe bilden,
weil sonst? Jetzt zum Double Overflow. Das ist
eine interessante Diskussion
Also A, haltung, doch hier. Ja,
es kann sein, dass es da in irgendwelchen Grenzfällen andere Ergebnisse rauskommen.
Ich schiebe die Diskussion mal kurz nach hinten, weil über Gleitkommazahlen diskutieren,
ohne dass ich darüber eine halbe Stunde nachgedacht habe, geht eigentlich nicht vernünftig.
Könnte sein, dass es sinnvoll ist, ES zu dividieren, ja.
Ich will mich da jetzt nicht zu weit aus dem Fenster lehnen.
Okay, gut, wenn du sonst keine Fragen mehr sind, ja?
Ehrlich gesagt, warum musst du das Ganze nicht als Public oder was?
Oh, falls ich vergessen habe. Wenn man hier nicht Public davor schreibt,
dann hat das eine besondere Bedeutung, die erst eine SE2 kennenlernt,
aber ich kann schon mal verraten, Ja, soll ich es verraten?
Ja, also wenn ihr das Public nicht hinschreibt,
dann ist die Sichtbarkeit so ähnlich wie Public,
nur in größeren Projekten, wo ihr sagt,
diese Klassen tue ich mal in Paket X und diese Klassen tue ich mal in Paket Y,
dann macht das einen Unterschied und Paket,
da kennt ihr noch gar nicht.
Also macht am besten alles Public oder Private,
weil sonst fragen euch eure Übungskundenlater, was bedeutet das denn,
wenn das Public oder Private fickt und das werdet ihr dann wahrscheinlich nicht wissen.
Ja, dankeschön. Okay, es ist das Objekt weg.
Ich schaue noch mal kurz, dass es wirklich exakt dasselbe macht.
Wir können ja noch zwei andere Werte nehmen,
was weiß ich,
40 und
Genau. Ja, dann würde ich sagen,
kommen wir wieder zurück zum Wurzelziehen,
was wir ja eigentlich machen wollten, was unser eigentliches Ziel war.
Dann nennen wir die doch mal, klassisch heißt die immer Root.
Jetzt habe ich auch schon verraten, dass sie ein Double zurückliefert.
Wie muss denn die Parameterliste aussehen? Wie viele Parameter muss
ich reinstecken können? Wenn ich zum Beispiel sagen will,
ich will die Wurzel von 100 berechnen oder ich will
die Wurzel von 81 berechnen oder von 42 oder so.
Wie viele Parameter brauche ich dann?
Nein, genau. Das ist sicherlich auch ein Double.
Vielleicht würde ich mal von irgendwelchen Kommazahlen die Wurzel berechnen.
Und als Mathematiker nennt man das dann meistens
Okay. Ja, es gibt ja ganz viele tolle Verfahren
zum Wurzelziehen. Ich habe das ja eben schon angesprochen,
das ist das sogenannte Newton-Verfahren. Also wir raten erst mal.
Ich mache das jetzt mal genauso, wie ich das gemacht habe.
Ich rate erst mal das Fünf, die Wurzel von XS.
Könnte ja sein. Vielleicht habe ich ja Glück,
vielleicht ist der Benutzer ja so blöd und steckt 25 rein.
Dann hätte ich gleich richtig geraten. Okay. Jetzt können wir uns überlegen,
wir wissen jetzt, wie lang eine Seite dieses Recht-Exits ist.
Wir wissen, welche Fläche das Recht erkannt.
Wie lang ist dann die andere Seite?
Wisst ihr das noch?
Was haben wir dafür getan? Wir hatten ja 100 durch 5 geteilt.
Was müssen wir da für allgemein machen, ja?
Wir müssen X durch G teilen. Also wir haben jetzt also zwei Werte,
ich schreibe das jetzt mal nicht Java-mäßig hin, sondern erstmal so informell.
Wir haben also einmal die Seitenlänge G. Dann haben wir die Seitenlänge X durch G.
Und ich würde jetzt gerne den Mittelwert aus diesen beiden bestimmen.
Ich habe diese eine Seite zu kurz, die andere Seite ist zu lang.
Jetzt will ich den Mittelwert bestimmen. Wie kann ich denn,
wenn ich zwei Double zahlen habe, den Mittelwert daraus bestimmen?
Ja. Ja, begleite ich auch so,
dass er vom Job ist. Sehr schön,
weil wir haben ja gerade diese schöne Methode geschrieben,
die das berechnet im Mittelwert.
Also ich rufe jetzt
das Average auf
So übergebe diese beiden Zahlen, einmal das G, einmal das X durchgehe.
Und damit das nicht verloren geht, müssen wir das jetzt irgendwo speichern.
Wollen wir dafür eine neue Variable machen oder wollen wir
das in irgendeiner Variante speichern, die schon da ist?
Habt ihr da irgendwie Vorschläge? Ja. Wir können uns
einfach wieder in G reinsetzen, weil dieser blöde Schätzwert 5,
der würde mich nicht mehr interessieren, nachdem ich einen schöneren Schätzwert gefunden habe.
Das ist interessant. Also das ist, du hast es
glaube ich schon letzte Woche gesagt, es ist keine mathematische Gleichung.
Also hier wird nicht behauptet, dass in G derselbe Wert drinsteht,
wie der Mittelwert aus G und X durchgeht,
sondern hier steht, liebes Java,
bitte ruf doch mal die Average-Funktion auf mit diesen beiden Werten.
Hier, bitte übergibt diese beiden Werte. Und was auch immer da zurückkommt,
stopft das bitte wieder in die Variable G rein.
Das bedeutet das. So,
das jetzt nur einmal zu machen, da wird man,
glaube ich, nicht besonders nah an den echten Wert rankommen.
Deswegen machen wir das einfach ein paar Mal mehr.
So, vielleicht. Ich habe das jetzt einfach mal zehnmal gemacht und
jetzt haben wir so einen schönen Wert in G drin.
Und jetzt haben wir euch oben versprochen,
dass wir ein Double zurückliefern.
Wie mache ich das denn
Wie liefere ich einen Double zurück aus der Funktion und welchen sollte ich zurückliefern?
Sehr gut. Return Gay, weil InG steht ja
der Wert, an den ich zurückliefern will, tatsächlich.
Mal sehen, ob das übersetzbar ist.
Okay, der Compiler beschwert sich nicht. Dann wäre es
doch jetzt sicherlich sinnvoll, das mal auszuprobieren.
Also ich mache hier einen Haltepunkt in unsere neue Root-Methode.
Erzeugt ein Objekt, nennt das mal wieder weh.
Und jetzt wird es spannend. Jetzt sage ich,
ich möchte die Wurzel von, nehmen wir ruhig die 100,
dann ist es dasselbe Beispiel wie in meinen wunderbaren Paint-Beispielen
Okay. Also X hat den Wert 100, klar,
ich habe ja gesagt, der formale Parameter X,
da habe ich ja das 100 quasi reingesteckt,
habe ich ja gerade interaktiv eingegeben.
Dann wird jetzt diese G-Variable angelegt. Das heißt,
momentan sind wir in dem Algorithmus so weit,
dass wir sagen, wir sind der Meinung,
5 ist wahrscheinlich die Wurzel von 100. Okay.
Und jetzt mache ich mal ein Step-Into, das kennt ihr ja
auch aus Carol. Hier steht ein Aufruf einer Methode,
ich will reinspringen in den Aufruf. Und jetzt ist eine
spannende Frage. Was passiert denn jetzt im Sinne dieser Parameter-Übergabe
? Also dieser Parameter G Wird zugewiesen an A. Also der
aktuelle Parameter G wird an den formalen Parameter A zugewiesen.
Und dieser aktuelle Parameter X-Durchgeh wird an den formalen Parameter B zugewiesen.
So funktioniert die Parameterübergabe. Man schaut sich an,
ich habe eine Liste von aktuellen Parametern.
Ich habe eine Liste von formalen Parametern, dann werden die
einfach quasi ja wie so einen Reißverschluss so zusammengesippt.
Das G gehört zu dem A und das X-Durchgeh gehört zu dem B. Das heißt,
was würdet ihr jetzt erwarten, welche Werte A und B dann haben müssten,
wenn ich da reinsteppe?
Welchen Wert wird A haben?
Fünf. Weil, ich will ja G übergeben,
G ist kein konstanter Wert, sondern eine Variable,
dann muss ich nachgucken, was steht denn drin,
da steht ja eine Fünf drin, also wird eine Fünf übergeben.
Okay. Welchen Wert wird das B haben,
wenn ihr euch hier diesen aktuellen Parameter anguckt, X durchgeht?
Ja. 20, sehr schön, weil wir müssen nachgucken,
was steht denn X, da steht 100 drin,
was steht RG, da steht 5 drin,
100 durch 5 bis 20. Wir würden jetzt also erwarten,
wenn ich Step Into mache,
dass A den Wert 5 hat und BNW 20.
Und genau so ist es auch, keine Überraschung.
Okay, dann werden jetzt über diese Zwischenschritte gemacht,
also wir addieren das mal auf,
das ist dann
Da sind wir. Dann halbieren wir das mal,
das müsste zwölfeinhalb sein, da sind wir.
Und jetzt steht hier Return Half, das heißt also,
diese 12,5 ist quasi das Ergebnis dieses Aufrufs.
Dieser Aufruf hat also den Wert 12,5 und diesen Wert 12,5
stopfen wir dann jetzt wieder in die Variable G rein.
Also ich hoffe mal, wenn ich jetzt Step drücke,
das G dann anschließend nicht mehr den Wert fünf hat,
sondern den Wert 12,5. Okay,
er hat die Zahlung noch nicht komplett ausgeführt,
er hat jetzt quasi, er muss jetzt noch die Zuweisung machen.
So,
jetzt haben wir
es gemacht
Gut. Was ist 12,5 ein besserer Wert als 5 Führer?
10 ist ja eigentlich das echte Ergebnis. Okay,
wir gehen noch einmal rein, damit wir es wirklich verstanden haben.
Also 12,5 wird an A zugewiesen und 8,
8 an B. Schauen wir mal, ob das passiert.
Ja, genau. 12,5 und 8. Dann werden die
wieder aufhatiert, ist ungefähr 20. Dann wird es halbiert,
ist so ungefähr 10, ein bisschen mehr.
Dann wird diese 10,25 zurückgegeben und an das G wieder zugewiesen.
Jetzt sind wir schon verdammt daran. Wir haben
nur zwei Iterationen gemacht. Und schon stimmt alles vor
dem Komma
10 ist ja das echte Ergebnis, das ist doch nicht schlecht
, oder? Also wir sind von 5 zu 12,5,
dann zu 10,25. Und jetzt gehe ich mal nicht rein in die Methode,
sondern überspringe das mal und ihr werdet sehen,
dass der Wert ziemlich schnell ziemlich gut ist.
Ja, also ich hätte möglicherweise gar nicht so viel Ernährungsschritte machen müssen.
Also das hätte mir gereicht, ehrlich gesagt.
Okay, mal gucken, was jetzt noch weiter passiert.
Jetzt ist es genau 10 und jetzt ändert sich hier auch nichts mehr, ne?
Jo. Und dieses Return G wird jetzt wieder dafür sorgen,
dass Bluejoy mir so eine Box aufflappt und sagt,
pass auf, hier ist eine 10 zurückgekommen.
Da ist sie. Er hat gesagt,
du hast Root aufgerufen, hast 100 als aktuellen Parameter übergeben
und als Ergebnis kam der Double 10,0 zurück
Gut. Irgendwelche Fragen zum Thema Parameterübergabe und Ergebniszurückgabe.
Das sieht man eigentlich wunderbar, alles jetzt hier in
diesem Quertext, was wir gerade gemacht haben. Ja,
du willst irgendwie, dass er das dynamisch so oft macht,
bis es irgendwie gut genug ist oder so.
Da gibt es einige interessante Ansätze, du könntest machen,
ich mache das so lange,
bis sich der Wert von denen nicht mehr ändert,
da müsstest du eine Schleife in dem Schlafen kommen,
erst in zwei Wochen oder so
Weil ihr kennt ja Schleifen schon aus Carrier,
vielleicht kannst du erraten, wie man es dann in Java macht.
Oder du speicherst dir alle Ergebnisse,
die jeweils mal rauskommen und du sagst,
sobald da ein Ergebnis rauskommt, was ich schon mal hatte,
dann lasse ich es sein, weil es kann ja sein,
dass es immer zwischen zwei Ergebnissen hin und her auszieliert.
Das könnt ihr euch dann mal überlegen,
das hat dann nicht mehr viel mit Java zu tun.
Aber es gibt auf jeden Fall Möglichkeiten. Ja. Das hätte man
nicht bei Imagie, das ist ungleich wenigstens. Ah,
du willst sozusagen, der Wurzelwert, den ich glaube,
wenn ich den mit sich selbst multipliziere, müsste ja X rauskommen.
Es kann sein, dass das nicht für alle Zahlen funktioniert.
Es könnte sein, dass es eine Double-Zahl gibt,
wo es keine exakte Wurzel gibt, die im Computer dargestellt werden kann.
Und wenn du die dann mit sich selbst mutiplizierst,
dass dann nur fast, dass das richtige Ergebnis rauskommt,
dann hättest du eine Endlosschleife.
Also da muss man höllisch aufpassen. Könnt ihr doch gerne
einfach mal zu Hause ausprobieren, das Rahmenwerk dazu habt ihr jetzt ja sozusagen schon.
Und natürlich ist es auch immer ein toller Streifpunkt,
was nimmt man denn jetzt mal als ersten Schätzwert?
Normalerweise ist man da fair gegenüber den sehr großen und den
sehr kleinen Zahlen und nimmt da einfach eins.
Eins ist sozusagen dann im Mittel ungefähr für alle Zahlen gleich schlecht.
Aber das wäre jetzt für mein Beispiel blöd gewesen,
dann wäre mein 100-Euro-Schein extrem platt gewesen.
Gut, sollen wir es noch fragen? Dann zeige ich
euch vielleicht noch mal einen Fehler, den Anfänger gerne machen.
Den habe ich ja Jahre lang beobachtet.
Und ich konnte mir nie erklären, wo dieser Fehler herkommt.
Und ich glaube, gestern habe ich ihn zum ersten Mal verstanden.
Jetzt könnt ihr davon profitieren. Also es gibt viele Anfänger,
die schreiben Void-Methoden, weil das kennen sie aus Carol so,
da muss ich an Void stehen.
Und dann geben sie auch natürlich nichts zurück.
Man darf ja nichts zurückgeben aus einer Wortmethode,
ich zeige euch das kurze Compiler, wird sich beschweren,
hey, aus einer Wortmethode kannst du nicht zurückliefern.
Na gut, wenn man das nicht darf,
dann löschen wir die Zahlen halt.
So. Und dann gibt es viele, die sagen,
na gut, dann rufe ich doch erstmal die Average-Methode auf.
So. Und dann könnte ich doch einfach den Inhalt der
Variable Half einfach in G abspeichern
So quasi, weil sie sagen,
in Half steht doch der Wert drin, der mich interessiert.
Und das funktioniert nicht. Kann mir jemand sagen, warum das nicht funktioniert?
Du weißt es, ich war noch mal kurz,
dass du ein bisschen darüber nachdenken können, warum kann das nicht funktionieren?
Da hast du noch eine Hand, so langsam gehen
die Hände hoch. Du hattest heute noch nichts gesagt.
Weil Half, das ist noch ein bisschen lauter?
Half, meine ersten Methoden entstehen nicht.
Genau, Half ist also eine lokale Variante.
Diese lokale Variante gibt es nur in diesem Bereich
Und wenn jetzt die Average-Methode verlassen wird, dann wird
diese Variable zerstört, die gibt es dann nicht mehr.
Die ist weg. Ihr könnt nicht in einer Methode auf
lokale Variable in einer anderen Methode zugreifen,
weil diese lokalen Variablen verschwinden, wenn aus der Methode zurückgegangen wird.
Der Compiler wird euch hier sagen, ich kenne dieses Hafen nicht,
ich habe keine Ahnung, was das sein soll.
Schauen wir, ob er das wirklich macht. Ja,
Cannot Find Simul variable half. Und vielleicht im Compiler irgendwann mal so anfängergerecht,
dass er euch vielleicht eine schönere Fehlermeinung sagt, pass auf,
lies noch mal im Skript auf Seite sowieso.
Die Variable gibt es in einer anderen Methode,
wenn du darauf irgendwie zugreifen willst,
dann musst du sie zurückliefern aus der anderen Methode
Ich repariere das jetzt also mal wieder, wenn diese Information
nicht verloren gehen soll, dann musst du sie zurückliefern.
Und dann musst du natürlich auch dann entsprechend die dem G wieder zuweisen.
Ich lösche jetzt einfach mal diese Zeile. Hier unten seht ihr
, wie es richtig ist. Also was auch immer,
dafür ein Ergebnis zurückkommt, ihr müsst es dann in G wieder abspeichern.
Ja. Okay, jetzt haben wir noch 25 Minuten,
noch Fragen, sonst würde ich, ja. Ich meine,
das sind Leute, die schon neue Programmierspeicher,
ganz neue wesentlich, denn der ist nur global,
das ist auch, glaube ich, in dem Bild.
Das könnte ja sein, es gibt Programmiersprachen,
wo man wirklich auf alles überall zugreifen darf
Ich bin noch mal auf der Bühne gekommen.
Ja, genau. Also es gibt Programmiersprachen,
die nicht so restriktiv sind und sagen, es gibt Bereiche,
wo die Variabien da sind und außerhalb der Bereiche gibt es die nicht.
Vielleicht liegt es daran, könnte sein. Man weiß es
nicht, ne? Okay. Gut, also das war
jetzt quasi der imperative Teil. Ihr habt jetzt verstanden,
wie Parameter übergeben werden und wie Ergebnisse aus Funktionen zurückkommen.
Dann gehen wir doch jetzt mal zum Objekt orientierten Teil.
Und machen den Klassiker. Entweder ist es immer
ein Konto oder ein Sparbuch oder ein Girokonto.
Das könnt E-Mails sagen. Wer will ein Sparbuch bauen?
Nicht so viele Leute, wer will
ein Konto bauen
Ein paar mehr Leute oder ein Girokonto,
ich weiß gar nicht, was so der Unterschied ist.
Wir bauen ein Konto. Bau mit dem Konto. Gut. Okay,
euer Template und Luja sieht immer ein bisschen aufgeräumter aus.
Das ist ja furchtbar, was hier alles immer automatisch generiert wird.
Ride und Discryption of Clusmodel. Okay, sagen wir mal
Exemplare dieser Klasse sind Konten. Und einfach so als kleine Herausforderung,
damit das Beispiel nicht ganz so langweilig ist,
sage ich immer ganz gerne, die nicht überzogen werden können.
Ich weiß nicht, ob das realistisch ist,
sonst sind es eben von mir aus
doch Sparbücher
Ich will also, dass da immer Geld drauf ist und dass
ein Benutzer irgendwie nicht das Konto überziehen kann oder wie Schulden machen kann.
So, das sind irgendwie, wir schreiben das heute noch zusammen.
Und heute ist, was haben wir heute?
4. November. Gut. Jetzt hatten wir ja schon gesehen,
ich glaube sogar schon letzte Woche, dass so eine Klasse,
gerne immer in drei Ölbereiche eingeteilt wird.
Wir haben einmal die Felder, wo man sich also Gedanken
macht, welchen Zustand hat so ein Konto.
Dann kommen die Konstruktoren, wo man sich Gedanken macht,
wie wird so ein Konto in die Welt gesetzt.
Und dann haben wir Methoden, wo man sich Gedanken darüber macht,
wie kann ich mit so einem Konto umgehen,
wenn es denn erstmal da ist
Fangen wir doch mal hier mit an. Welchen Zustand hat
ein Konto? Muss ich da jetzt irgendwelche Strings ablegen oder so?
Was sollte ich da auf jeden Fall reintun ins Sonnenkonto?
Ja. Jo, genau, den Kontostand.
Und eine Sache hatte ich auch noch gar nicht gesagt.
Das würde ich gleich von vornherein machen, dass ihr nicht
irgendwie in diese Falle reinlauft. Viele Programmierer denken,
naja, so ein Kontostand soll ja vielleicht sein,
sowas wie 1,50 oder wenn ich ganz reich bin, 2,75 Euro oder so.
Deswegen wollen sie gerne Komma zahlen für Kontostände nehmen.
Und ich wollte euch einmal ganz kurz zeigen,
steht auch auf dem aktuellen Aufgabenblatt, warum man das nicht tun sollte.
Wenn ihr zum Beispiel hier eine Direkteingabe angibt,
Ich habe irgendwie 10 Cent auf meinem Konto und bin nochmal 20 Cent drauftun.
Müsste ich ja eigentlich 30 Cent auf dem Konto haben,
ne? Ja, so ungefähr. Okay. Ja,
und diese Effekte sind für Geld irgendwie nicht so schön,
da hätte man gerne so ein, ah,
irgendwie nicht so komische Effekte gerne und wir werden nächste Woche noch erkunden,
warum diese komischen Effekte bei Double auftreten und auch bei Float.
Okay, also ich sage jetzt mal,
ich will tatsächlich für den Kontostand ein Int nehmen,
Kontostand ist so ein langes Wort, ich schreibe einfach mal Saldo,
das ist ja dasselbe.
Aber habe ich jetzt ein Problem,
also wie kann ich denn jetzt sagen,
ich will irgendwie 10 Cent oder 20 Cent auf meinem Konto haben,
wenn ich nur ein Int habe und ich gar nicht
sagen kann,
0,1 oder
Ja, wir speichern den einfach in Cent. Problem gelöst,
wir brauchen keine Kommazahlen mehr. Sehr schön. Ja,
vielleicht schreiben wir das hier noch mal für zukünftige Programmierer hin.
Lieber Zukunfts-Fred. Nicht wundern. Wir speichern den Saldo in,
ich sag mal, Euro-Cent. Das ist ein schönes Wort,
oder? Weil es gibt ja auch Cent in anderen Währungen.
Okay. Deswegen brauchen wir keine Kommazahlen. So. Okay,
dann freut sich vielleicht der nächste Programmierer.
Da kann man sich noch Gedanken machen,
ob man da noch weitere Sachen speichern will,
wie wem gehört das Konto oder eine Kontonummer oder wann
wurde es erzeugt oder so.
Das lassen wir jetzt mal, wir machen das jetzt erstmal so einfach wie möglich.
Ein Salto sollten wir auf jeden Fall speichern.
Okay. Ja, dann sollten wir uns Gedanken machen,
wie wird so ein Konto in die Welt gesetzt?
Wie mache ich das denn? Wie sieht denn so ein Konstrukt
da aus? Ist das auch irgendwie so ein Public Voice
oder wie schreiben wir da nochmal einen Konstruktor in Java?
Kann das noch jemand aus der Folie rezitieren oder soll ich
es einfach hinschreiben? Ihr schreibt es einfach mal hin.
Und ihr sagt mir, ob ihr sowas schon mal gesehen habt.
Public Konto. So, das sieht ja irgendwie komisch aus.
Das sieht ja fast so aus,
als wäre das eine Methode,
nur dass hier
kein Rückgabetyp steht
Ja, und ihr erkennt Konstruktoren tatsächlich daran,
sie definieren keinen Rückgabetyp und sie heißen genauso wie die Klasse.
Und kamen auf den vorhin schon vor,
ich wiederhole das jetzt einfach nochmal. Gut. Und ja,
es ist immer ganz gerne so ein lustiges Szenario,
wenn man ein neues Konto bei der Bank eröffnet.
Die freuen sich natürlich in den heutigen Zeiten,
dass man das Geld noch auf die Bank bringt.
Vielleicht geben die einem so einen kleinen Eröffnungsbonus.
Also wie könnte ich zum Beispiel sagen,
der Saldo soll 10 Euro sein, so ein kleiner Begrüßungsbonus.
Ja. 10.000, auch das ist immer eine
sehr großzügige Bank
Wir speichern Euro-Cent, genau. Das heißt, das wären
die Cent. Und dann haben wir davor, sind das
10 Euro? Das sind irgendwie 100, ne?
Ja, sagen wir lieber C, das ist realistischer.
Okay. Gut. Sehr schön. Das heißt also,
wenn ich ein neues Konto erzeuge, müsste der Saldo 1000 sein.
Das probieren wir gleich mal. Achso, nächste,
ich schreibe das vielleicht noch mal als Kommentar darüber.
Dass einen das nicht verwundert, auch für den Benutzer dieser Kontoklasse.
Also ein neues Konto wird mit 10 Euro Start.
Saldo in die Welt gesetzt.
Schauen wir mal ganz kurz, ob das hier in der Dokumentation auftaucht,
die habe ich euch auch letzte Woche gezeigt.
Hier, ne? Ihr seht also alle Konstrukturen,
bis jetzt gibt es nur ein neues Konto, wird immer 10 Euro starten,
sondern in die Welt gesetzt, ist doch schön.
Dann probieren wir das mal aus, ob das funktioniert.
Ich erzeuge mir also ein Konto. Und jetzt,
tja, das ist doch so ein bisschen enttäuschend, ne?
Blue Jay sagt mir sogar, no accessible methods at,
also keine einzige Methode gefunden, die Public ist.
Es liegt daran, dass es keine einzige Methode in einem
Objekt gibt, folgt dich auch keine Depublic ist.
Ich kann jetzt mal schummeln und mit dem Objektinspektor gucken,
wie das Objekt denn so aussieht und oh,
toll,
dieses Konto hat den Kontostand
Joe. Gut, also wir haben uns Gedanken gemacht,
welchen Zustandard zum Konto wir uns Gedanken macht, was ist ein sinnvoller Startwert.
Und jetzt sollten wir vielleicht mal anfangen, Methoden für das Konto zu schreiben.
Was ist das erste, was am Anfang,
was man mit so einem Konto gerne macht?
Abheben. Das ist das Wichtigste. Also, lieber.
Ciao. Fehlt da jetzt nicht noch irgendwas? Also,
ich muss ja irgendwie sagen, also wenn ich zum Bankschalter
hingehe oder auch wenn ich auf irgendeinen Automaten rumklicke,
ich muss ja sicherlich, ja.
Das geht ja noch. Genau, wie viel wollen wir
denn abheben
Wie viel wollen wir abheben? Nennen wir das mal Betrag
. Das ist so ein klassischer Parametername für Geldbeträge.
Okay. Und was will ich jetzt in der Methode machen?
Also ich habe 1.000 Euro, 11. 1.000 Cent auf meinem Konto.
Und nehmen wir mal an, ich will jetzt 100 Cent abheben.
Was muss ich dann hier drin tun?
Damit anschließend mein Saal nur noch 900 ist.
Ja? Das ist halt das Gleiche, minus den Betrag.
Okay, also wir müssen eine Rechnung. Ah,
okay, du bist also schon bei der End
Lösung hier sozusagen so, ne? Genau,
das ist auch schon wieder so eine Stelle,
wo man aufpassen muss, Achtung, Achtung,
das ist keine mathematische Klarheit, ach Entschuldigung, minus,
das wäre ja auch toll, ne?
Okay. Also ich bitte Java, etwas auszurechnen. Ich bitte Java,
schau doch mal nach, was in dieser Variante steht.
Schau doch mal nach, was in dieser Variante steht.
Okay, jetzt habe ich irgendwie zwei Zahlen.
Dann subtrahiere die beiden Zahlen bitte, da kommt dann
irgendein Ergebnis raus, in unserem Fall 900.
Und diese 900 stopfe ich dann wieder in den Saido zurück rein.
Ich überschreibe also den Wert von Sado mit diesem neuen Wert.
Ja, das können wir doch gleich
mal wieder kommentieren
Hebt einen Betrag von deinem Countdoor. Das probieren wir einmal
. Kann ich das wieder so geschickt layouten,
dass ihr den Code gleichzeitig seht.
So, machen wir uns mal ein Konto.
Hier ist es. Und jetzt hebe ich mal Geld ab.
Ja, nehmen wir mal ruhig. Ich brauche zwei Euro.
Ich habe irgendwie wie mit dem Bier kaufen oder so.
Gucken. Ah ja, seht ihr, jetzt hat sich der Saldo geändert.
Jetzt haben wir nur noch 800 drauf, ne?
Und ich habe wirklich eine Party feiern und brauche
noch mehr Geld.
Oh,
das ist ja doof
Jetzt habe ich mein Konto überzogen. Ich wollte ja eigentlich
gar nicht, dass es möglich ist. Wie kann ich
denn jetzt in Java sagen? Das soll nur gemacht werden,
wenn man dadurch nicht irgendwie ins Negative kommt. Ja,
du weißt ganz viel, irgendeiner, der heute noch im
Nichts soll, das ist auch schon, ja.
Ja, wenn der Betrag kleiner ist als der Sailor,
dann wollen wir das irgendwie tun.
Ich habe es, so, ne? Kleiner gleich.
Ach stimmt, ich kann es auch leer rollen.
Ich weiß nicht, ist das erlaubt,
dass man gar nichts aus seinem Konto hat
Weiß ich gar nicht. Müsstet ihr dann mal eure Auftraggeber fragen,
ob das erlaubt ist, dass man gar nichts auf dem Konto hat?
Weiß ich ehrlich gesagt nicht. Das kommt immer ein bisschen darauf an,
welche Bank das jetzt gerade ist. Okay. Tja,
was macht man denn jetzt? Es wäre irgendwie schön,
wenn der Benutzer so irgendwie eine Art von Feedback darüber kriegt,
wenn er da irgendwie Unsinn eingegeben hat.
Und da macht man gerne etwas, das haben wir,
ich weiß nicht auch, haben wir euch das schon gezeigt?
Ich glaube nicht. Ich schreibe dann einfach mal irgendwie
eine Fehlermeldung auf die Konsole. Ich könnte irgendwie schreiben,
es ist nicht genug Geld auf dem Konto. Irgendwie so. Ja,
und wenn ihr irgendwie noch fleißig seid,
schreibt ihr vielleicht auch noch die konkreten Werte da rein,
damit der Benutzer noch genau weiß,
warum das jetzt nicht geklappt hat
So, ich mache, achso,
ich habe das Objekt sicher gar nicht, wo ist es?
Hier ist es. So, dann hebe ich mal wieder ab,
ich mache mal wieder das, was geht, also 200 kann ich abheben.
Okay, habe ich noch 800 drauf. Wenn ich jetzt
irgendwie 900 versuche abzuheben, dürfte sich das Objekt nicht ändern
und es müsste stattdessen irgendwie so diese Konsole aufploppen mit dieser Fehlermeldung.
Jo, da ist sie, ne? Ihr werdet später noch
saubere Möglichkeiten kennenlernen, dass man irgendwie mit Ausnahmen umgeht,
das kommt aber erst in SE2, die sogenannten Exceptions im Genre.
Okay, aber immerhin hat sich das Konto nicht verändert,
das ist doch schon mal gut, ja?
Ich konnte also nicht irgendwie ins Negative kommen.
Habt ihr dazu noch fragen bis jetzt?
So ein kleines iF. IF kennt ihr ja schon aus Kerl.
Man kann eben in Java auch iF verwenden und hier irgendwelche,
ja, kleiner, gleich größer, ungleich.
Das gibt es also eben hier alles in Java.
Ja. Das ist man jetzt innerhalb der Firma,
so viel Art mit Gerät schon früher, ein Zwei-Läger-Fan ist.
Ich bin der, der sagt, jede Abfängnis bei hundert.
Sehr gut, also man sollte nicht irgendwie negative Beträge übergeben.
Also man müsste irgendwie auch noch zusätzlich überprüfen, ja,
wenn der Betrag, wie muss er sein,
größer als null oder größer gleich neu?
Größer als neu, oder
Ja, aber ich glaube, da fühlt sich der Bankangestellte verarscht,
wenn ich da hingehe und sage, ich will 0 Euro abheben.
Machen wir uns aber lieber so, ja,
um den Frieden zu wahren. Ich glaube,
der Bankangestellte ist, dass der Gaser, die Kontakte führen.
Okay. Ja, ich will es lieber nicht provozieren.
Okay. Und ansonsten könnten wir wieder irgendeine Fehlermeldung rausgeben.
Was wollen wir dann sagen? Man kann nur
positive Beträge abheben oder so. Irgendwie so, ne?
So. Bitte schreibt hier nicht in Fehlermeldungen 4711 oder so.
So wie andere Softwarefirmen das gerne machen.
Ja, das testen wir auch nochmal ganz kurz,
dass das auch funktioniert. Ah, ja, genau.
Ich bin minus 200 abheben. Ja. Man kann nur
positive Beträge abheben. Und diese Meldung ist noch von eben,
vielleicht ist es ganz nett, man kann hier irgendwie einstellen,
Clearscreen and Method Call, sonst seid ihr oft verwirrt.
Moment, kamen diese Fehlmeldungen jetzt gerade eben oder ist die schon fünf Minuten alt?
Ich aktiviere diese Option einmal. Und dann müsste er sozusagen
immer nur die aktuelle Meldung auf der Konsole anzeigen.
Also nochmal irgendwie minus 300. Man kann nur positive Beträge abheben.
Und wenn ich sage, ich will irgendwie ganz viel abheben,
müsste er sagen, dass das zu viel ist.
Ja, nicht genug Geld auf dem Konto. Okay,
ich glaube, dann haben wir ja alle Fehlerfälle so abgefangen,
die man hier so machen kann.
Also der Betrag an sich muss positiv sein,
das wird quasi hier geprüft und man darf nicht zu viel abheben, das wird hier geprüft.
Frage? Richtig, es kommt nichts aus, das bedeutet,
ich will nochmal den Unterschied verdeutlichen, was bedeutet das,
wenn hier Void steht? Void bedeutet,
diese Methode kann beliebig viele Änderungen an Objekten hervorholen,
sie kann den Salde hochzählen, sie kann den Salde runterzählen,
sie kann neue Objekte erzeugen, was auch immer.
Aber das Besondere ist, wenn ich sage, hebe ab,
zum Beispiel 200, dann wird jetzt keine Box aufploppen,
wo steht,
es kam eine 800 zurück oder es kamen die 42
zurück oder es kam irgendein anderes Ergebnis zurück
Aber von der Vorstellung, die haben wir ja vorhin gemacht.
Richtig, aber diese Fehlermeldung ist nicht ein Volt. Und es ist,
diese Fehlermeldung erscheint ja auch nicht in so einem Kästchen,
sondern die wird als kleine Nebenwirkung, wird die auf die Konsole geschrieben.
Das ist was anderes. Also etwas auf die Konsole zu schreiben,
ist was anderes, als zu sagen,
ich liefere ein Ergebnis an den Aufruferzeug,
mit dem man weiterrechnen kann.
Du kannst mit Fehlermeldungen nicht rechnen. Du kannst nicht sagen,
also bei Average konnte ich sagen, liebe Average-Funktionen,
liefer mir einen Wert. Da kam zum Beispiel 12,5 zurück
und dann mache ich mit der 12 mal von irgendwas machen.
Du kannst aber nicht zum Beispiel Fehlermeldungen addieren oder
Fehlermeldungen in Variablen speichern oder so
Nee, eine Fehlermeldung ist Rainer Checks. Das wird nicht
irgendwie weiter interpretiert und du kannst es auch nicht weiterverarbeiten.
Das wird einfach nur so gelockt sozusagen auf der Konsole,
wie so ein Flugschreiber, der irgendwelche Daten auf dem Papier raufschreibt.
Damit wirst du nichts mehr machen können. Es sei denn,
das Flugzeug stürzt irgendwann mal ab. Ja. Das war,
das Restrikan, den Ernstsatz ist durchaus verfressen,
den Frieber mit der, das trinkt so gut,
liebt die Ohren, das ist die Feind für den Tenorpatrinzen,
trinkt die Schlacht, das war der neue Gottesstaat,
das war stark, dann wäre das genau dieser Ernst.
Ah, du willst einen String zurück,
zurück, zurückgehen anstatt gar nicht.
Das könnte man
tatsächlich machen
Und aus Spaß können wir das auch gerne mal tun,
damit ihr den Unterschied quasi seht.
Das ist ganz witzig, weil ich glaube,
in Aufgabe 2 auf dem Blatt müsst ihr sowas ähnliches auch tun.
Dann habt ihr es mal gesehen. Also man könnte tatsächlich
sagen, dieses Hebe ab soll eine Fehlermeldung zurückliefern.
Das ist jetzt quasi deine Motivation, ne? Okay,
gut, das ist ja so sehr unkonventionell,
das würde man normalerweise nicht machen, aber ich zeige euch mal,
wie es geht, dass ihr es mal gesehen habt.
Okay, dann sage ich also hier nicht,
ich will es auf die Konsole schreiben, sondern ich sage,
ich würde es zurückgeben.
Ich gebe das als Ergebnis dieser Methode zurück.
Da mache ich das hier auch
Stimmt. Wer glaubt, dass sich das jetzt übersetzen kann?
Ich habe das Blut vorbereitet, diese Frage.
Wer glaubt, dass man es nicht übersetzen kann?
Ah ja, Tatsache. Warum? Weil der Compiler sagt,
naja, es gibt jetzt ja irgendwie drei Fälle.
Entweder alles ist in Ordnung oder es ist nicht genug Geld auf
dem Konto oder du hast irgendwie eine negative Zahl übergeben.
In diesem Fall gibst du ja gar keinen String zurück.
Du hast aber versprochen, dass auf jeden Fall
ein String aus dieser Methode zurückgeliefert wird.
Das heißt, wir müssen jetzt hier einen String zurückliefern,
zum Beispiel alles okay
Das Typsystem verlangt das von uns.
Deswegen ist das für Fehlermeldungen wahrscheinlich eigentlich nicht so gut,
dass man sagt, ich gebe jetzt immer einen Streng zu.
Man könnte auch den leeren Streng zurückgeben, Büro.
So, jetzt zeige ich euch nochmal kurz den Unterschied.
Das ist gleich also nicht so eine Konsole aufploppt,
sondern dass dann dieses klassische falsches Objekt,
dass dann dieses klassische Fenster auflaut mit dem Ergebnis einer Funktion.
Also wenn ich so sage, ich will was Negatives abheben,
dann würde er mir sagen, das Ergebnis dieses Aufrufs,
also du hast im Konto eins, hast du Heber abgerufen,
du hast minus 100 übergeben und das Ergebnis ist,
man kann nur positive Beträge erfüllen.
Also es ist wirklich sehr,
also sowas macht es mit den echten Projekten nicht,
Fehlermeldungen als Strings zurückgeben.
Das ist jetzt nur so
eine kleine technische Demonstration
Normalerweise werden Fehlermeldungen ganz anders gemacht. Okay,
oder wenn ich irgendwas Sinnvolles tue, was weiß ich so,
dann würde mir sagen, dass alles in Ordnung ist, ne?
Ja. Okay, aber dann habt ihr ja mal gesehen,
man kann auch tatsächlich Strings aus der Methode zurückliefern.
Das wird euch für Aufgabe 2, glaube ich, ganz nützlich sein.
Da sollte ja sowas ähnliches nämlich auch machen. Okay,
wir haben noch 5 Minuten, wollen vielleicht nochmal die,
ich mache das jetzt, ich lasse es jetzt so,
wir haben nicht mehr so viel Zeit.
Ja, auf jeden Fall. Achso, du willst sozusagen,
dass der aktuelle Saldo als Drink zurückgegeben wird?
Ach, warum nicht? Könnte man machen.
Erstmal der naive Versuch. Ich versuche, den Saldo zurückzugeben
Da wird das Typ-System ja auf den Finger klopfen und sagen,
nee, nee, nee, du musst einen String zurückgeben,
aber Saldo ist ja ein Int.
Incompetible types. Einfacher Trick ist, ihr nehmt einfach
den leeren String und hängt den Sald oder Inter.
Das ist so die einfachste Möglichkeit. Gibt auch viele andere kompliziertere Möglichkeiten,
aber ich finde, die kann man sich immer am besten merken.
Okay, gut, aber wir haben nur noch wenig Zeit.
Ich will jetzt mal zu dem Einzahlen kommen.
Also ich mache jetzt mal wieder so,
wie es eigentlich gedacht ist, dass nichts zurückkommt,
zahle ein,
ob es Endbetrag,
dann sagen wir Hops
Jo, das ist heute ein Betrag, auf ganz kurz.
Und vielleicht hätte man hier auch noch sagen sollen,
der Betrag darf nicht negativ, negativ sein.
Oder machen wir das hier auch? Und das ist auch
noch ganz spannend, das vergesse ich auch mal fast,
euch das zu erzählen.
Also ihr seht jetzt ja hier das in der Dokumentation,
zwei deutsche Sätze stehen. Beide enden mit einem Punkt.
Und wenn ich jetzt mal mir die Dokumentation angucke,
dann seht ihr interessanterweise bei der Zusammenfassung der Methoden
immer nur den ersten Satz
Also bei Hebe ab, hebt einen Betrag von einem Konto
ab. Mehr steht jetzt hier erstmal nicht,
man will jetzt den Programmierer nicht überlasten.
Also in der Zusammenfassung sollte ja nicht alles stehen.
Wenn ich jetzt aber hier raufklicke, dann seht ihr,
dass hier alles steht. Also nicht wundern,
wenn vielleicht nur der erste Satz in der Dokumentation auftaucht.
Okay, ja, muss ich hier irgendwelche Sonderfälle beachten?
Irgendwas reinkopieren. Ja, ich schreibe es dir dann nochmal
neu für die Übung. Also ich kann sagen,
der Betrag muss größer als nöser.
Okay. Ansonsten könnt ihr euch, oh,
könnt euch hier eine sinnvolle Fehlermeldung überlegen
Und jetzt, tja, ich glaube,
ich hatte letzte Woche schon mal angefangen, darüber zu reden.
Nehmen wir an, ich habe relativ viel Geld auf meinem Konto und ich will noch mehr Geld drauftun.
Funktioniert das immer? Oder gibt es irgendwie Grenzen in dem Rechner,
die mir sagen, du kannst nicht beliebig hoch werden als am Ende?
Ja. Wo sie jetzt nicht auch als theoretisch hoch. Ja,
also mit dem Geld, was wir hier so verdienen,
wahrscheinlich so schnell nicht,
aber wenn vielleicht mal irgendjemand anders dieses Programm benutzt,
weiß jemand, wo so ungefähr die Grenze ist von innen,
dass man irgendwann nicht mehr, irgendwas mit einem Milliarden,
ne?
Genau,
und das sind ja nur 10 Millionen Euro,
also okay
Gut, wie könnte ich denn jetzt prüfen? Also,
wenn ich den Betrag auf den Saldo drauf addiere,
will ich nicht, dass dieser blöde Overflow quasi passiert.
Kann man das irgendwie abprüfen mit einem IF? Da hat
jemand einen coolen Vorschlag, wie man das abprüfen könnte.
Ja. Das ist explodierend mit aktuellen Zeiten und Zufall hier,
also in der Führung des Podcasts sind wir eingezahlte Vertrages.
Ah, nicht schlecht. Ich glaube,
dass wir Interager Max-Version erst nächste Woche kennenlernen werden,
aber das ist eine gute Lösung.
Hat jemand noch eine andere Idee, so eine völlig naive?
Also ich sage ja schon so quasi,
also wenn ich die Addition durchführe,
könnte es ja passieren,
dass was Negatives rauskommt
Kann man das nicht direkt so auch programmieren, ja?
Also das Ergebnis der Addition, kleiner.
Dann hätten wir ein Problem, ne? Genau,
das heißt, ich kann zum Beispiel einfach sagen,
wenn der Saldo plus der Betrag, ja,
was Positives ist, dann hat es offenbar geklappt.
Das ist die Frage, ob das passieren kann.
Könnt ihr euch Gedanken machen bei diesen Randfällen?
Also hier ist sozusagen alles in Ordnung, dann kann ich
das einfach machen. Saldo ist gleich Saldo plus Petra.
Ansonsten, ja, würde ich wahrscheinlich
eine Federmeldung ausgeben
So viel Geld passt leider nicht auf ein Konto.
Tja. Das ist aber so ein Randfall,
den müsst ihr von mir aus nicht unbedingt programmieren.
Das ist so eine besondere Eigenschaft von Java,
jetzt so geht da, Int geht nur bis zwei Milliarden,
dann kann ich ja nur 20 Millionen auf mein Konto tun.
Also wenn ihr das jetzt nicht macht in den Übungen,
dann ist es, glaube ich, nicht schlimm.
Aber andersrum, wenn ihr es macht, dann strahlen wahrscheinlich
eure Übungsgruppenleiter und freuen sich. Jetzt sehe ich gerade noch,
wir berechnen ja hier quasi diesen neuen Saldo zweimal.
Das ist ja auch irgendwie blöd. Kann ich das irgendwie
so machen, dass der nur einmal berechnet wird?
Neuer Saido, ne? Genau. Tops.
Das ist so eine Art, also der Probesaido sozusagen.
So, oder? Also ich versuche das erstmal zu machen,
speichere mir das Ergebnis in der lokalen Variable und dann prüfe ich,
wenn da was Sinnvolles ausgekommen ist,
dann kann ich die neuen Saido tatsächlich in den echten Saldo übernehmen.
Ansonsten, muss ich sagen, sorry, da hättest du uns einen Overflow gegeben.
Das passiert nämlich, wenn ich über das Maximum zugehe.
Was passiert, wenn man über das Maximum geht?
Das zeige ich dir einmal,
Also vorhin hat es ja der eine schon angesprochen,
es gibt diesen speziellen Wert, den weiß ich nicht auswendig,
das könnte man aber auch hinschreiben.
Ich nehme ihn jetzt einfach mal, dass es nicht so
magisch wirkt. Ich nehme diesen Wert, ob es,
das ist der größte Int, den es gibt.
Unteridiere ich jetzt mal einen rauf. Kommt was Negatives,
Wort. Frisst sich natürlich ja genau da ist. Ja,
also wenn du jetzt quasi da nochmal zwei Millionen drauf kriegst,
dann bist du bei null.
Also es ist wie so ein riesiger Kreis quasi.
Int ist also kein Zahlenstrahl, sondern ein Zahlenkreis.
Und sobald du über den Größen eben drüberkommst,
bist du beim Kleinsten und dann musst du dich wieder ganz
hoch ackern zur Null und dann musst du wieder zum Größen kommen und dann landest du wieder beim Kleinsten.
Es ist wie so eine Uhr so ein bisschen,
nach elf Uhr kommt null Uhr und nicht zwölf Uhr.
Okay. Ja, es ist 15.45 Uhr,
vielen Dank.
Bis nächste Woche