Ja, willkommen zur dritten Vorlesung von SE1. Ich sage ganz gerne,
wenn man am Anfang so auf so ein paar andere Worte über die Folien hinaus.
Ich habe letzte Woche schon so ein bisschen was gesagt zu
den Begriffen, die wir hier verwenden.
Dass wir zum Beispiel die Exemplare, Exemplare nennen und nicht Instanzen.
Und der gute Mark Zwain hat mal gesagt, dass das irgendwie,
der Unterschied ist zwischen dem richtigen Wort und dem fast richtigen Wort,
wie zwischen dem Blitz und dem Glühwürmchen,
das,
glaube ich,
meinte er eher für Prosa
Ich glaube, so bei technischen Systemen, wie wir das hier haben,
kann man das ein bisschen in Frage stellen.
Also es gibt kein richtig oder falsch bei diesen Benennungen.
Es gibt höchstens etwas, was wir sehr wichtig finden,
nämlich konsistent. Das habe ich auch letzte Woche schon gesagt.
Wir verwenden die Begriffe hier relativ, nein, nicht relativ,
sondern ziemlich konsistent. Es gibt so eine ganze Menge Begriffe,
die sozusagen außerhalb dieser Veranstaltung verwendet werden.
Zum Beispiel ist es auch so, dass die Zustandsfelder,
wie wir sie nennen,
oder die Felder von den Objekten,
die werden in manchen Büchern
auch Instanz variablen genannt
Wir nennen sie dann auch Exemplarvariablen in einer Klassendefinition.
Also alles verschiedene Begriffe. Es gibt aber auch Kontexte,
da heißen die Dinger dann Attribute. Kann man drum streiten
. Also Attribut finde ich keinen so passenden Namen.
Deswegen haben wir uns hier auf einen anderen Namen entschieden.
Aber das Entscheidende ist, dass wir hier konsistent sind mit unseren Begriffen.
Was auch noch vielleicht ganz interessant ist, was ich einem kurz loswerden will.
Ich hatte in der Übung in der letzten Woche einen Studenten,
der hat die Aufgabe 2, wo es darum ging,
die Schnittstelle des Zeichners zu erweitern,
dass man auch einen Parameter übergeben kann,
um die Farbe der Hauswand
Des Hauses, was da getan hat, wird zu bestimmen.
Und der Student hat versucht, das mit Vererbung zu lösen.
Das heißt, er hat irgendwie die Klasse Zeichner von irgendeiner anderen Klasse erben lassen,
hat dann irgendwas versucht mit Labels zu arbeiten,
also mit Swing-Google-Komponenten, lauter Zeug,
von dem die meisten von euch noch nichts gehört haben müssen.
Das Problem war, der gute Mensch saß mit jemandem zusammen im Paar,
der keine Vorerfahrung hatte und er selber hatte Informatik-Leistungskurs.
Das ist dann immer ganz spannend. Für diejenigen,
die schon viel Vorerfahrung haben, die möchte ich bitten,
dass sie versuchen, sich zu beschränken auf das,
was wir bisher vorgestellt haben.
Wir sind sehr konsequent da drin, nur die Begriffe zu
verwenden und abzufragen und abzufordern, die wir auch eingeführt haben.
Das heißt, das baut aufeinander auf, aber wir bauen
auch auf nichts mehr auf, als das, was wir einführen.
Also wir fordern nicht, dass ihr jetzt plötzlich ganz andere Sachen können müsst.
Also für diejenigen, die schon mehr wissen, wäre es gut,
wenn sie mit ihrem Wahnsinnsvorwissen ein bisschen hinterm Berg halten und das nicht gleich vergeuden für Leute,
die dann vielleicht eher verwirrt sind, als dass es ihnen hilft.
Und für diejenigen, die noch keine Programmiervorerfahrung haben,
für euch ist es, glaube ich, ganz gut,
wenn ihr an bestimmten Stellen einfach auch sagt, Was ist denn das jetzt?
Das verstehe ich nicht. Was machst du da? Das
steht hier nirgends im Skript, das ist nirgends vorgekommen.
Und dann auch vielleicht dann jemanden herholt, einen Betreuer,
dass man mal so ein bisschen darüber diskutiert, wie man das lösen kann,
weil das einfach dann auch für euch nicht viel bringt.
Also wenn ihr da mit Sachen konfrontiert werdet, die ihr nicht kennen könnt.
Da müsst ihr also ein bisschen Selbstvertrauen entwickeln. Da müsst
ihr auch mal sagen, nö, das können wir doch gar nicht wissen.
Das ist was, was noch nicht dran war.
Also insbesondere das Thema Vererbung kann ich euch versprechen,
wird in diesem Semester gar nicht thematisiert werden.
Wir werden nicht über Vererbung sprechen. Und wenn irgendjemand im Übungsbetrieb sagt,
das geht mit Vererbung, alles viel einfacher, dann könnt ihr sagen,
ja, das kann sein, aber wir brauchen hier in SE1 erstmal keine Vererberung.
Eine Spezialfall von Vererbung werden wir thematisieren, aber das kommt später. Okay,
dann habe ich letzte Woche ja mal Storesi benutzt für eine Quizfrage und für eine nicht triviale Quizfrage,
falls ihr euch noch erinnert, das war so eine Klassendefinition,
die sah so ein bisschen absurd aus,
das ist ganz wichtig, dass ihr versteht,
dass Programmiersprachen irgendwie aufgebaut sind, also hier so eine Klassendefinition,
da gibt es Sprachen wie Java, die legen fest,
wie sowas aussehen muss und da muss man diese Elemente,
die da irgendwie drin vorkommen,
die muss man identifizieren können.
Man muss wissen, was ist das und wofür
ist das da? Und ich habe eigentlich alles erzählt,
was man wissen musste, um das lösen zu können.
Es war relativ leicht zu erkennen, dass es zwei Zustandsfelder sind,
weil wir ja hier konsistent Zustandsfelder mit Unterstrichen benennen.
Wenn wir sie deklarieren. Es war nicht so leicht zu erkennen,
ob das jetzt hier drei Methoden sind oder ob es
zwei Methoden sind und ein Konstruktor oder ob es,
ja tatsächlich sind es dann zwei Konstruktoren, ja,
ein parameterloser Konstruktor und ein Konstrukter mit einem Parameter.
Also sind es zwei Konstruktoren und nur eine einzige Methode,
die in dieser klassische definiert sind
Das muss man erst mal lernen,
dass da bestimmte Regeln gelten, dass man die anwenden muss,
um weitere Schlüsse ziehen zu können oder so etwas.
Apropos Sturesi, ich habe mal wieder eine Abstimmung mitgebracht.
Ich will jetzt mal was anderes fragen. Ich will jetzt mal so
ein bisschen versuchen zu Anfang immer so eine Umfrage zu machen.
Ich weiß nicht, ob das immer klappt,
ob mir da auch eine gute Frage einfällt,
was ich in den ersten beiden Terminen versäumt habe,
war etwas, was ich fragen wollte.
Nämlich diese Frage hier,
In welcher Objekt- und hier eine Sprache hattest du vor SE1,
also bevor ihr diese Veranstaltung besucht habt, die meiste Erfahrung.
Und ihr könnt natürlich antworten, wenn ihr keine Programmiererfahrung habt,
keine Vorerfahrung mit Europäern. Das ist vollkommen in Ordnung.
Und alle anderen, die schon irgendwas mit OOP gemacht haben,
also mit objektorientierter Programmierung, wir sollen doch einfach mal sagen,
in welcher Sprache die die meiste Erfahrung haben.
Braucht noch irgendjemand den Barcode hier?
QR-Code. Mist, das war der Falsche.
So hier ist der QR-Code
Ja. Reicht. So, hier läuft die Abstimmung noch.
Das sind jetzt so, ja, 100, 70.
Das sollte eine Frage sein, die man relativ schnell beantworten
kann,
würde ich vermuten
Guck mal, ob die Frage jetzt ja auch wirklich sichtbar ist.
Ich habe ja auch so ein komisches Gerät hier.
In welcher Objekte und dem Sprache genau A bis G.
Also hier habe ich ja dann noch zur Auswahl gestellt Java
C Plus Plus C Sharp Objective C, für diejenigen,
die für iOS schon programmieren,
Delphi und dann vielleicht noch eine andere Sprache.
Gut, 200 Stimmen, wunderbar. Wir gucken einfach mal
. Es ist immer ganz interessant, so zu sehen,
welche Sprachen gerade en vogue sind. Keine Vorerfahrung,
das ist das Übliche, so 35 Prozent hier ungefähr 34.
Und dann 30 Prozent Java. Dann gibt es Paar,
die haben CPlus-Erfahrung, immerhin, fast 10 Prozent.
Das sind vermutlich die, die sich hier in weiten Teilen
langweilen, könnte ich mir vorstellen.
Und dann haben wir hier auch noch immerhin 10 Prozent Delphi Turbo Pascal.
Das ist ganz interessant. Gut, wir werden dann nochmal
so zwischendurch so ein oder zwei Fragen stellen.
Gut. Ja, dann geht es heute um imperative Grundkonkonzept.
Ich habe in den ersten beiden Vorlesungen so ein bisschen
die Basics von Objektorientierung euch erzählt, Objekte, Klassenmethoden,
Zustand,
Zustandsfelder,
Jetzt gucken wir uns mal ein paar imperative Grundkonzepte an,
die auch in Java drinstecken. Aber diese imperativen Grundkonzepte sind universell
. Das heißt, was ich jetzt erzähle, heute,
insbesondere was heute drankommt, das ist nicht beschränkt auf Java.
Das sind grundlegende Dinge, die man in jeder Programmiersprache braucht,
tatsächlich sogar auch in Programmiersprachen, die nicht objektorientiert oder imperativ sind.
Auch in funktionalen Sprachen gibt es so etwas wie Funktionen
und da gibt es sowas wie Parameter.
Wir werden uns heute angucken, wie Parameter genau funktionieren.
Also die erste Hälfte der Prozedurbegriff, zu Dua, der andere Name für Methode.
Und in der zweiten Hälfte gehen wir dann so ein bisschen darauf ein,
wie das mit der Übersetzung von Java funktioniert.
Und insbesondere wie die Klassendefinition,
die er ja schon ein bisschen gesehen hat, wie die aufgebaut sind,
dass wir das mal ein bisschen systematischer uns angucken,
wie man das formal beschreiben kann, nämlich mit Hilfe von Syntaxbeschreibungssprachen.
Da gucken wir uns die IPNF an.
Gut, sehr schön. Der Einstieg,
das Konzept fast aller Computer ist der sogenannte von Neumann-Rechner
Das ist eine bestimmte Art von Architektur, wie Computer funktionieren.
Wenn ihr Rechnerstrukturen besucht, dann werdet ihr da sicherlich
deutlich mehr drüber hören. Wer die Veranstaltung nicht besucht,
da geben wir halt hier so einen kleinen Überblick. So ein Computer,
wie ihr ihn kennt, sogar eine Hosentasche habt,
der sieht letztendlich konzeptuell ungefähr so aus,
wobei hier jetzt fast alles fehlt, was da sonst noch so dazugehört,
was ihr normalerweise benutzt.
Also hier ist kein Screen dabei, kein Keyboard,
vor allen Dingen keine Festplatte, üblicherweise bei einem Computer habe ich eine Festplatte,
wo ihr Dinge dauerhaft speichert.
Hier geht es nur darum, wie funktioniert einen Computer,
damit er irgendetwas ausführen kann, ein Programm ausführen kann.
Und da beschränkt man sich halt üblicherweise auf diese Darstellung.
Das heißt, es gibt sowas wie die CPU,
also hier irgendwo so eine Zentraleinheit. Und dann gibt es
den Hauptspeicher. Das sind so zwei zentrale Einheiten.
Dankeschön. Ein Werk von den vier Werken ist das Speicherwerk der Hauptspeicher.
Also einfach ganz viele Speicherzellen, in denen Daten abgelegt werden können,
wenn der Strom abgeschaltet wird, ist der ganz,
ganz, ganze Zeug weg, was im Speicher ist.
Das ist sozusagen das Basismodell. Und dann gibt es so etwas wie einen Bus,
über diesen Bus transportiert die CPU-Informationen aus dem Speicher in diese zentrale Einheit.
Da gibt es, dass ein Ausgabewerk, da wird unter
anderem auch werden Festplatten angeschlossen und ähnliche Dinge, Plastaturen.
Und dann gibt es hier das Rechenwerk,
da wird tatsächlich gerechnet, also so Additionen, Multiplikationen,
sowas ist in den Rechnern heutzutage eingebaut,
in den Prozessoren
Und hier gibt es das Leitwerk. Und das ist sozusagen
das Gehirn, das Hirn der CPU.
Da ist es tatsächlich so, dass das aktuelle Programm,
was gerade abgearbeitet wird, aus dem Speicher geholt wird.
Das ist eine ganz zentrale Eigenschaft von Neumann-Rechner.
Vor dieser Architektur, das war in den 50er Jahren,
hat der von Neumann das entworfen.
Da war das so, dass ein Computer Anweisungen ausgeführt hat,
aber diese Anweisungen waren fest eingebrannt.
Die waren fest hier eingebrannt. Und was hier im
wechselhaften Speicherstand,
das waren Daten
Da wurden also Daten von da irgendwie geholt, irgendwie verarbeitet und wieder zurückgeschrieben.
Aber das Programm selbst stand in der CPU.
Der von Neumann-Rechner ist deshalb so wahnsinnig spannend,
weil der so universell ist, in dem Sinne,
dass in dem Speicher sowohl Programme stehen als auch die Daten.
Das heißt, das, was da wirklich gemacht wird,
steht auch im Speicher. Und das funktioniert eigentlich ganz einfach
. Es gibt den sogenannten Fetch-Execute oder Fett holen,
Fett holen und ausführen, Zyklus, Fetch-Execute-Cycle.
Das heißt, hier in der CPU gibt es ein Register,
das ist der Programmzähler. Und der sagt,
dieser Programmzähler sagt, in welcher Speicherzelle im Hauptspeicher
der nächste auszuführende Befehl steht
Und dieser Zyklus beginnt dann,
in dem aus dieser Zelle der Befehl in die CPU geholt wird,
in der CPU dekodiert wird, dann wird festgestellt,
oh, es handelt sich um einen Additionsbefehl.
So, jetzt brauchen wir noch Operanten,
also holen wir uns nochmal Daten aus dem Speicher.
Dann wird der eine Operant geholt, dann wird der andere Operant geholt,
läuft alles über den Bus und dann wird das irgendwie verarbeitet und dann wird es wieder zurückgespeichert.
Und dann wird der nächste Befehl ausgeführt,
das heißt also, dieser Befehlszähler hier in der CPU,
der wird einfach um eins erhöht und es wird der nächste Befehl
geholt und dann wird er wieder dekodiert und dann ausgeführt.
So funktioniert eigentlich wirklich jeder Rechner, den ihr so
vor euch habt. Es sind nur noch Spezialrechner,
die das nicht so machen
Und es ist tatsächlich so, dass dieser Speicher hier,
der Hauptspeicher ist, in Zellen gleicher Größe eingeteilt.
Das sind üblicherweise heutzutage 32 Bit 64 Bit. Das Programm besteht aus
einer Folge von Befehlen, die prinzipiell erstmal nacheinander ausgeführt werden.
Genau diese sequenzielle Ausführung. Von der sequenziellen Opfer kann man
durch Sprungbefehle abweichen. Kann man dann irgendwie sagen,
jetzt lade ich einfach mal die Adresse von einer anderen Stelle,
wo Code steht.
In den Befehlszähler und dann kann ich einfach genau da weitermachen.
Das ist also so, was mehr oder weniger aus dem Computer passiert.
Und die Maschine benutzt Binärcodes, sowohl für die Darstellung von Programmen
als auch von da. Das ist also alles Binär,
könnte ich mir das vorstellen,
dass in diesem Speicherlauter Null und Einzel stehen
Die dann so gebündelt sind, in Worten.
Und jedes Wort hat 32 oder 64 Bit, je nachdem.
Gut. Das heißt, diese imperativen Programme,
die wir ja jetzt schon so ein bisschen kennengelernt haben,
hier so Java-Programme, die werden auf solchen von Neumann-Maschinen ausgeführt.
Das heißt, wir sind relativ nah dran an der Maschine
mit der imperativen und Objekte und dem Programmierung.
Wir machen also etwas, was eine Abstraktion ist darüber,
was der von Neumann-Rechner so tut. Also CPU führt Maschinenbefehle aus,
aber wir werden über den sogenannten Bus,
Befehler und Daten vom Speicher übertragen und die Ergebnisse zurück übertragen,
habe ich eben erzählt.
Und die imperativen Programmiersprachen, die abstrahieren da so ein bisschen von.
Die haben sozusagen, die ziehen eine Schicht drüber und sagen,
naja, wir haben Anweisungen und wir haben Variable
Das kennt ihr schon, also Anweisungen in einem Java-Programm,
die stehen da so im Rumpf einer Methode und werden sequenziell ausgeführt.
Und dann gibt es sowas wie Variablen,
die dann tatsächlich vom physischen Speicherplatz abstrahieren,
wo man dann Werte drin abspeichern kann und dann aber auch diese Werte hintergespeichert sind, ändern kann.
Auf der von Neumann Maschine werden diese Befehle nacheinander ausgeführt und vom Steuerwerk
nacheinander in den Prozessor geholt und dann dekodiert und verarbeitet und durch Sprungbefehle kann man abweichen.
Und auf der Ebene von der Programmiersprache wie Java,
also einer höheren Programmiersprache, gibt es sogenannte Kontrollstrukturen,
die habe ich auch schon erwähnt, Sequenzfallunterscheidung,
Wiederholung und wir haben ja uns schon die Sequenz ausführlich angesehen.
Fun-Unterscheidung und Wiederholung kommt noch. Da gucken wir doch mal
ein bisschen genauer drauf. In der übernächsten Woche.
Und was wir uns heute ein bisschen genauer ansehen wollen,
sind diese Methodenaufrufe, die ihr ja auch schon kennengelernt habt.
Also wenn ihr in Blue Jay, ich kann ja mal,
zufällig habe ich Blue Jay dabei,
hier mal starte und ich jetzt hier mir diese Klasse Zeichner mal angucke,
ihr ja schon kennt.
Das ist jetzt für euch hoffentlich relativ vertraut. Dann hattet ihr
die Aufgabe, hier so eine, die Methode Zeichne,
die schon da ist, ein bisschen zu erweitern,
dass man da so eine Parameter übergeben kann.
Das ist jetzt schon relativ langweilig, das schmeiße ich einfach mal raus.
Die Methode ist ja von euch schon voll verstanden.
Die Siti ist ziemlich lang, ist nicht so schön.
Es sieht nicht so gut aus, wenn solche Methoden so lang sind.
Also, dann haben wir jetzt hier eine Methode, die heißt Zeichnerhäuser.
Wir sehen, es ist eine Methode, weil sie fängt
irgendwie hier mit Public an und hat hier diese runden Klammern.
Also ist es eine Methode, sonst wäre es vermutlich eine Exemplarvariable.
So, also hier, das ist eine Methode und die sieht relativ überschaubar aus.
Hier steht nämlich genau hier. Und natürlich gehört der Kommentar
mit dazu, deswegen ist es hier auch gelb unterlegt.
Ganz wichtig, wenn ich mir das jetzt hier übersetze,
dann habe ich hier in dieser Klasse,
ich kann das hier mal ein bisschen runterscrollen,
die nächsten Methoden, die da kommen, sind private.
Die sind alle private. Das heißt,
wir haben nur eine öffentliche Methode,
wie ich das übersetze und mir die Schnittstelle ansehe,
dann sehe ich da nur genau eine Methode Zeichenhäuser.
Und Zeichenhäuser zeichnet drei Häuser gleiche Architektur mit unterschiedlichen Wandfarben und
einer Sonne.
Hier steht also der Kommentar, der für einen Klienten interessant ist.
Derjenige, der als Klient wissen will, was macht denn diese Methode?
Der kriegt hier einen Text, der das genau beschreibt.
Deswegen finden wir es relativ wichtig,
dass wir früh euch damit anfreundet, wenn ihr Methoden schreibt,
die an der Schnittstelle stehen, also public sind,
dass ihr dann auch schreibt, was macht diese Methode?
Und zwar so schreibt, dass ein Klient,
der nicht euren ganzen Quelltext durchlesen will, weiß,
was das Ding tut, damit er dann weiß,
ob er es benutzen will.
Deswegen finden wir das wichtig,
dass ihr diese Kommentare auch wirklich schreibt. Das lernt,
sie zu schreiben, dass ihr es übt und das
möglichst früh macht
Okay, diese Methode sieht jetzt hier so aus,
dass hier eine zeichne Sonne aufgerufen wird, zeichne Hauszeichen nach Hauszeichen aus.
Also drei Häuser werden hier gezeichnet, habe ich letzte Woche,
glaube ich, schon mal gezeigt.
Wir können das nochmal eben kurz ausführen, falls da Interesse besteht,
dass ihr auch wirklich seht, dass da was passiert.
Hier zeichne Häuser, also drei Häuser werden gezeichnet.
So, also und im Quelltext ist das, ah,
ich mache das Ding mal wieder zu,
das brauchen wir erstmal nicht.
Im Quelltext sieht das hier so aus,
dass hier in dieser Methode jetzt
andere Methoden aufgerufen werden
Also Methodenaufruf, darum geht es jetzt. Was passiert denn bei so
einem Methodenaufruf? Hier wird irgendwie, zeig eine Sonne aufgerufen,
jetzt stehen hier irgendwelche komischen, kryptischen Zeichen.
Also das sind wir ja schon hoffentlich ein bisschen mitbekommen,
das sind die aktuellen Parameter. Also die Methode, Zeichner,
Häuser, wird hier zum Klient der Methode Zeichen Sonne.
Ruft die Methode Zeichen Sonne auf und übergibt dann konkrete Werte,
die dann tatsächlich da weiterverarbeitet werden.
Das heißt, mit diesen Parametern wird festgelegt,
wo denn die Sonne hingezeichnet wird
Zeichne Sonne ist universell,
zeichne Sonne zeichnet nicht nur eine Sonne an einen bestimmten Punkt,
sondern man kann zeichne Sonne sagen, mach sie dahin oder mach sie dahin.
Sehr schön. Parametrisierend, Parameter, ein sehr mächtiges Konzept.
So, und hier sieht man jetzt Zeichnerhaus,
wird hier dreimal aufgerufen, jetzt habe ich hier Zeichenhaus,
und da wird dann Zeichen eine Wand aufgerufen und so weiter.
Also, dass tatsächlich hier mehrere Methoden nacheinander aufgerufen werden,
wenn ich das hier von Hand aufrufe,
also wenn ich tatsächlich Zeichnerhäuser aufrufe,
dann werden weitere Methoden aufgerufen.
Das gucken wir uns ein bisschen genauer an jetzt
Also Methodenaufrufe sind spezielle Anweisungen, die greifen auch in den sequenziellen Ablauf ein.
Ist klar, das wird nacheinander ausgeführt, aber dann wird ja irgendwo anders hingesprungen,
da wird irgendwas gemacht und dann wird wieder zurückgekommen.
Ich erzähle das jetzt, im Folgenden unter dem Namen Prozedur. Immer wenn wir Imperative Begriffe wählen,
dann kommt ja hier der gestreifte Schlaumeier dazu,
der sagt uns, dass das ein Begriff ist,
der in der imperativen Programmierung allgemeingültig ist,
also nicht nur in der Objektorientierung,
sondern generell,
wenn du zum Beispiel mit Pascal programmiert oder in Basic vielleicht sogar programmiert,
dann gibt es da
auch Prozeduren
Manchmal heißen die auch Funktionen, also zum Beispiel in C
Plus Plus heißt die Dinger Funktionen, blöder Name dafür.
Oder wie heißen sie sonst noch? Mir fällt jetzt nichts weiter ein.
Mit der funktionalen Programmierung sind es natürlich dann auch Funktionen.
Aber wir abstrahieren das hier unter dem Begriff Prozedur.
Also in der imperativen Programmierung sind tatsächlich prozentuell das mächtigste Abstraktionsmittel,
wenn man so in Pascal früher programmiert hat,
da war das schon super zum Strukturieren von komplizierten Abläufen.
Wir haben das schon gesehen,
ich hätte das alles in eine Methode schreiben können,
aber ich kann auch schöne kleine, griffige Methoden schreiben,
die wenig tun und wo man sehr viel klarer weiß,
wofür sie da sind und kann die dann
elegant aufrufen
Also da geht es um Abstraktion. Das gilt genauso
für Methoden wie für Java. Also vieles, alles,
was ich jetzt sage, gilt auch für Methoden.
Wir werden dann noch am Ende sehen,
dass es für Methoden noch ein paar Dinge mehr gelten.
Okay, also eine Prozedur. Ja,
Prozeduren sind die Einheiten, die die Aktivitäten bestimmen.
In einem objektnotierten System ist das total richtig in Java.
Es passiert alles nur in den Methoden.
Und da steht immer das gleiche Konzept dahinter
Es wird irgendwie ein Algorithmus realisiert. Hier ist, würde ich jetzt,
wenn man so ein Hauszeichner nicht unbedingt von einem Algorithmus sprechen.
Deswegen ist das auch ein bisschen,
das haben wir nicht mehr unbedingt so en vogue,
gleich die Algorithmen in den Vordergrund zu stellen.
Softwaretechnisch, sagen wir eher, das ist eine benannte Folge von Anweisung.
Das heißt, wir haben da sowas wie Tour,
verschiedene Dinge zeichnen ein Dach und so weiter.
Und das nennen wir dann benannt, nennen wir das Zeichnerhaus.
Die Grundidee ist dann, dass dieser Name der Methode
stellvertretend für genau diese Anweisung steht.
Das ist ganz praktisch. So,
und dann können wir eben halt Parameter übergeben und
auch das müssen wir uns mal
ein bisschen genauer angucken
Jetzt ist hier der Algorithmusbegriff schon so ein bisschen erwähnt worden von mir.
Der spielt halt in der Informatik eine große Rolle.
Und wir können jetzt mal so ein bisschen genauer drauf gucken,
wie gesagt, ausführlich alles zu Algorithmen dann in anderen Veranstaltungen,
die Algorithmen und Datenstrukturen heißen oder Algorithmik und so weiter.
Hier aus, wenn man jetzt sozusagen auf die Programmierung kommt,
dann sagt man so ein Algorithmus,
das ist so die kleinste Einheit beim Programmentwurf.
Ganz wichtig, ein Algorithmus ist ein endlicher Text.
Also auch wenn wir jetzt auf so einen Methodenrumpf gucken,
was da so drinsteht,
das ist ja endlich,
ein endlicher Text
Und da wird ein Problemlösungsverfahren beschrieben. Und das besteht aus Aktionen.
Da hatte ich letzte Woche schon mal so kurz angedeutet,
die auf sprachlichen Einheiten arbeiten. Und das ist letztendlich das,
was ein Allgeordnet ausmacht, eine Folge von Anweisungen.
Und das ist üblicherweise sprachunabhängig. Also ein Algorithmus hat gerade die Eigenschaft,
dass er nicht in einer spezifischen Sprache formuliert wird,
also nicht in einer Programmiersprache, sondern abstrakter.
Und da gibt es natürlich dann auch Einheiten wie Variablen und Ähnliches,
die dann auch, wenn man solche Algorithmenbeschreibungen liest, trotzdem vorkommen.
Ein Algorithmus terminiert, das nennt man so,
wenn ein Algorithmus irgendwann mal endet, dann terminiert er.
Wenn er nicht nur in endlichen,
in die Vorschrift selbst nicht nur endlich ist,
sondern auch das, was er bewirkt an Ausführung,
wenn das auch nach endlich vielen Schritten beendet wird.
Wir können im Algorithmus einen Namen geben und dann können wir
da drin wieder weitere Algorithmen drin haben.
Also wir können jetzt hier auch nochmal sagen, also Zeichnehäuser ist ein Algorithmus,
in dem nämlich hier eine Sonde gezeichnet wird und drei Häuser gezeichnet werden.
Und jetzt kann man auch diese hier,
Zeichnehaus ist dann ja auch wieder ein Algorithmus,
wo dann hier im Detail steht, was denn Zeichnehaus macht,
nämlich eine Wand,
ein Dach,
ein Fenster auch eine Tür zeichnen.
Und das setzen wir in Prozeduren um. Und dann ist schon
eigentlich ja nachvollziehbar aus dem, was ihr schon gemacht habt.
Wir haben eine Anweisungsfolge, die irgendetwas macht.
Hier jetzt mal wieder ein ganz anderes Beispiel.
Max, wir wollen das Maximum von zwei Zahlen ermitteln.
BNA größer B ist, dann sagen wir, Maximum ist es gleich A.
Also Weisen der Varianten. Max, den Wert,
die Belegung der Variablen A zu. Ansonsten ist Max eben
B. Gut, und das ist erst mal eine Anweisungsfolge.
Die steht einfach irgendwo so im Quelltext.
Jetzt sagen wir, wir geben dem ganz normalen Namen.
Also irgendwie zum Beispiel hier in Maximum. Hier wird sozusagen
jetzt für eine Methode definiert, dass sie Maximum heißt für eine Prozedur.
Und als Ergebnis einen intliefert, nämlich genau das Maximum von A und B.
Und dann steht hier im Rumpf genau das.
Und dann steht hier am Ende ein Return Max,
also so liefere dann tatsächlich den Wert als Ergebnis zurück.
Okay, und das kann natürlich dann auch irgendwo aufgerufen werden. Das heißt,
hier kann irgendein Klient kann jetzt diese Methode oder diese Prozedur aufrufen,
Maximum von 6,9, nicht so eine wahnsinnig schlaue Idee,
das aufzurufen, weil jeder Mensch, der draufkommt,
sieht,
das Maximum von 6 und 9
ist doch
Spannender wird das natürlich, wenn da Variablen stehen,
die von woanders irgendwo eingegeben wurden, weit interaktiv und so weiter.
So, jetzt haben wir die Parametrisierung schon so ein bisschen gesehen.
Also man kann hier Parameter übergeben. Das ist ganz zentral,
ganz wichtig. Wenn wir so eine Dienstleistung von einem Dienstleister aufrufen,
so eine Methode aufrufen, dann ist es gut,
wenn da Parameter übergeben werden können,
weil dann kann ich irgendwie das noch steuern, was da passiert.
Ich kann also Einfluss nehmen auf die Dienstleistung. Wenn das parameterlos ist,
dann ist es einfach nur, mach es, tu es.
Aber wenn ich Parameter übergeben kann, dann kann ich noch es steuern.
Und was da passiert ist, dass Informationen ja übergeben werden müssen,
wenn ich zum Beispiel sage, zeichne das Haus an eine bestimmte Position,
da muss ich ja diese Position irgendwie mit rübergeben.
Von Neumann-Architektur, maschinener Assembler, da wird das gemacht,
in dem, in irgendwelche Speicherzellen,
irgendwelche Werte geschrieben werden und dann gesagt wird,
hier übrigens, du findest deine Parameter in diesen Speicherzellen.
Wir haben natürlich, wir sind jetzt hier da schon deutlich attraktiver unterwegs,
wir machen das mit getypten formalen Parametern. Klingt jetzt komplizierter,
als es ist, das kennt ihr ja schon,
dass die Parameter, die ihr deklariert habt,
zum Beispiel die Wandfarbe dass die auch einen Typ haben muss.
Okay. Jetzt gibt es, wenn ihr euch mit Programmierung beschäftigt,
und das fürchte, ich müsste ja in dieser Veranstaltung,
ganz viele Formen der Parameterübergabe.
Also die Welt der Informatik war da sehr kreativ in den
letzten 50 Jahren. Es gibt ungefähr, ich glaube,
sechs verschiedene fundamentale Übergabe, Mechanismen für Parameter in Programmiersprachen.
Wenn ihr euch mit Programmiersprachen beschäftigt, das ist echt,
das ist eine Welt für sich.
Das ist der nackte Wahnsinn
Das Schöne ist, wir machen das Ganze hier mit Java
und Dava hat nur genau einen Mechanismus, genau einen Übergabemechanismus.
Das ist total einfach. Nämlich Eingabeparameter oder auch Wertparameter.
Im Englischen Call by Value. Da ist es tatsächlich so,
der Parameter dient zur Übergabe von Informationen an die Prozedur.
Der Aufrufer gibt die aktuellen Parameter in Form von Ausdrücken an.
Da steht also irgendetwas. Da wird möglicherweise beim Aufrufer
irgendwas berechnet und das Ergebnis der Berechnung wird dann geben.
Die Werte der Ausdrücke stehen der gerufenen Prozedur unter dem formalen Parameternamen zur Verfügung.
Das habt ihr gesehen, wenn dann diese Methode aufgerufen wird,
dann hat ja der formale Parameter immer eine Belegung.
Da steht also irgendwas drin und damit kann jetzt in der Prozedur,
im Rumpf der Prozedur gearbeitet werden mit dem Wert.
So, und das ist tatsächlich der einzige Mechanismus, den Java bietet.
Es gibt keinen anderen Übergabemechanismus. Es gibt nur Eingabeparameter. Das heißt,
irgendetwas wird berechnet beim Aufrufer, das wird kopiert an den,
an die gerufene Methode und damit wird dann gearbeitet mit dem Wert.
Es gibt mindestens noch eine weitere Übergabeform für Parameter, die attraktiv ist.
Die C-Plus-Programmierer kennen das, auch wer C-Sharp schon mal programmiert hat,
wird wissen, dass es da mehr Mechanismen gibt.
Und ein relativ zentraler sind die Ausgabe oder variablen Parameter.
Das werden wir uns jetzt hier gar nicht angucken.
Das werden wir uns wahrscheinlich auch in SC2 nicht angucken.
Das ist, glaube ich, relativ gut verständlich,
wenn man erstmal diesen Mechanismus, diesen einen hier in Java gut verstanden hat.
Alles andere kommt später. Viele Leute glauben,
dass da war, doch sowas hätte wie Übergabe per Referenz
, Aber das ist ein Irrglaube.
Es ist, was dann tatsächlich übergeben wird, sind Referenzen.
Referenzen gucken wir uns später noch an. In Woche 5
kommt das noch ausführlich, ganz zentrales Konzept in Java.
Aber die werden auch einfach per Wert übergehen.
Die werden auch einfach kopiert, diese Referenzen. Deswegen also,
lasst euch nicht verwirren, wenn euch irgendjemand einredet.
Es gäbe verschiedene Möglichkeiten im Java Parameter zumindest. Es gibt
nur genau einen Mechanismus. Gut. Wenn wir jetzt also die Eingabeparameter,
die Java so hat, uns mal näher angucken wollen,
dann haben wir hier wieder unser Beispiel mit dem Maximum.
Und Maximum bekommt hier formale Parameter. Ihr wisst,
die formalen Parameter stehen da oben im Kopf einer Methode.
Bei einer formaler Parameter hat immer einen Typ und einen Namen.
Und die stehen halt da oben. Die stehen immer da
oben, die formalen Parameter. Gut, und dann gibt es
aufrufende Stellen. Das heißt, es kann Klienten geben,
die diese Methode aufrufen, diese Prozedur.
Und das kann von völlig verschiedenen Stellen passieren. Es kann ja so einem System,
kann es ja eine Maximum-Methode geben und dann ganz viele Klienten,
die das Ding benutzen, an ganz verschiedenen Stellen.
Ganz verschiedene Aufrufstellen. Da steht also wirklich im Quelltext,
steht entweder dieser Aufruf hier oder vielleicht auch dieser Aufruf
Und das sind tatsächlich die Klienten, die an den Stellen,
wo sie den Aufruf tätigen, aktuelle Parameter übergeben.
An der aufrufenden Stelle, aktuelle Parameter. Das sind Ausdrücke,
das heißt, ich kann da tatsächlich sowas hinschreiben wie zweimal X.
Ich kann also auch tatsächlich, wenn ich jetzt hier mal zeichne,
mir nochmal vornehme und zum Beispiel zeichne Sonne mal public mache,
Public setzen, jetzt kann ich ja das Ding hier tatsächlich Direkt aufrufen.
Zeichen der Sonne, kann ich hier aufrufen.
Jetzt kann ich hier in X-Post, in Y-Post angeben.
Das sind also anscheinend, das ist die Position,
wo dann der Mittelpunkt der Sonne auf der Leinwand sein soll.
Okay, und jetzt kann ich hier sowas angeben wie 200, 200.
Und dann wird mir hier da unten irgendwo an dieser Stelle 00 ist da oben.
Also irgendwo, hier wird jetzt die Sonne hingemalt.
Ich kann aber auch hier an dieser Stelle jetzt sagen,
150, minus 10 plus 30. Nicht besonders intelligent,
gebe ich zu
Ich kann das auch direkt ausrechnen, direkt angeben. Ich will nur zeigen,
ich kann an der aufrufenden Stelle einen beliebigen Ausdruck angeben.
Und auch hier kann ich jetzt fragen, dreimal 50. Juhu.
Und dann wird hier wieder eine Sonne gezeichnet. Irgendwo da
. Nur, dass ihr seht, das ist möglich,
dass man an der aufrufenden Stelle irgendeinen Ausdruck angibt, eine Berechnungsvorschrift.
Was Ausdrücke genau sind,
auch das sehen wir uns nächste Woche nochmal ausführlich an,
aber ihr habt schon mal so einen Eindruck.
Was ganz wichtig ist, die Parameter müssen vom richtigen Typ sein.
Das heißt, wenn ich jetzt hier zeichne Sonne aufrufe
Und jetzt hier, sagen wir, blau und lila übergebe,
dann wird das nicht funktionieren. Weil der Typ,
der Parameter sagt, hier müssen ganze Zahlen übergeben werden.
Int heißt ganze Zahl. Da muss ich auch irgendwas angeben,
was als Ausdruck ausgewertet, die ganze Zahl ergeben kann.
Ich kann dann mit Höhe auch Mühe geben,
kann jetzt hier noch schreiben, blau, plus gelb.
Dann kommt da vielleicht irgendwie ein Intro raus,
weil es eine Addition ist, aber ist nicht so.
Das sind hier zwei Zeichenketten und die werden mit Plus
einfach aneinander gehängt,
Also auch da kommt keine Zahl raus. Das heißt,
wenn ich das so aufrufe, dann kommt hier Arror incompetible types.
Die Typen passen nicht. Da gibt jemand Zeichenketten an,
der Aufrufer, aber der Dienstleister möchte unbedingt Ins haben.
Und der Compiler überprüft das schon an der Aufrufstelle,
dass das vom Typ auch passt.
Okay. Okay, das sind die aktuellen Parameter.
Dann gibt es ein paar Regeln,
das haben wir jetzt mehr oder weniger schon gesehen,
der Name im Aufruf definiert die zurufende Prozedur.
Ihr könnt also nur genau die Prozeduren aufrufen,
die auch wirklich da sind
Ihr könnt jetzt nicht irgendwie an dem Zeichner was anderes aufrufen.
Ich könnte jetzt ja hier sagen, Zeichner eins, Punkt,
zeichne Nase. Mach mal, zeichne mal eine Nase.
So. Ja, jetzt steht da Zeichner elf. Habe ich
schon gesehen, danke. Zeichne eins, zeichne Nase.
So, und jetzt sagt er hier,
cannot fine simple, mit method, zeichne Nase.
Klar, gibt es nicht. Das ist auch was,
was man sich klar machen muss.
Der Compiler überprüft natürlich, ob diese Methode wirklich da ist.
Es gibt Sprachen, da kann man einfach Methoden aufrufen,
auch wenn die nicht da sind
Dann sagt das Objekt, das dann aufgerufen wird, sagt dann,
ich verstehe die Nachricht gerade nicht, die du mir schickst.
Java ist das schon sehr früh unterbunden,
also da wird einfach geprüft, ob so ein Ding da
ist und dann wird es auch gar nicht erst aufgerufen.
Die Anzahl der aktuellen Parameter muss gleich der Anzahl der Formalen sein.
Wenn wir das hier bluteinteraktiv machen, geht es gar nicht anders.
Aber ich kann ja jetzt hier zum Beispiel sagen, zeichne 1.zeichne Sonne.
So, jetzt gebe ich hier nur eine 1 an.
So, nur einen Parameter. Ich muss
zwei Parameter angeben, gib nur einen an. Riesenactual,
mal gucken, was jetzt hier an Fehlermeldungen steht,
das kann man jetzt nicht
gut lesen
Arror, Method, zeichne Sonne in Klaas Zeichner,
Kennot, Apply to given types, required and int,
zwei Ins möchte ich haben, Found int.
Ich habe nur einen Int gefunden. Reason, actual and
formal argument list differ in längs. Also ja, ich
möchte zwei haben. Du hast mir nur einen gegeben,
das geht nicht. Die Bindung nach der Position,
also wenn da ein String und ein Int übergeben werden muss,
dann muss man die auch in der Reihenfolge angeben.
In Java ist das so festgelegt,
so wie sie da stehen, müssen sie auch übergeben werden.
Es gibt Sprachen, da kann man die Reihenfolge wieder ändern.
Es gibt alles. Es gibt alles in der Welt
der Programmiersprachen
Wir haben so ein Glück, dass wir hier so eine
einfache Programmiersprache haben. Das ist wirklich, wirklich gut.
Die aktuellen Parameter müssen typkompatibel sein, habe ich schon erzählt.
Das wird alles vom Compiler überprüft. Gott sei Dank,
ihr müsst das nicht alles selber prüfen.
Da klopft euch der Compiler auf die Finger.
So, jetzt gibt es auch so etwas wie Ergebnisprozeduren.
Wie haben wir jetzt wieder mal so was,
wo wir hier einen Begriff einführen, wo man sich fragen kann,
warum nennen die das denn Ergebnisprozedur?
Andere nennen das eine Funktion. Wir nennen es Ergebnisprozedur,
weil die Dinger, die da aufgerufen werden können,
die können ja auch ein, also die Methoden,
die aufrufen können, die können auch ein Ergebnis liefern.
Ich zeige eigentlich ein Beispiel, das ihr auch schon gesehen habt,
Girokonto, hier haben wir jetzt diese klassische Girokonto,
ich erzeuge ein Girokonto mit einem Anfangssaldo von 100.
So, und jetzt habe ich hier die Möglichkeit einzahlen und Gibsaldo aufzurufen.
Einzahlen kennt ihr, ist langweilig, Diebsaldo ist ein bisschen spannender,
aber ich gebe erstmal einen Zahlen aufrufen.
Einzahlen, jetzt wird ich hier gefragt,
wie viel willst du einzahlen, sage ich mal 20 Euro.
So, jetzt würde ich erwarten, dass bei Gibsaldo 120 rauskommt.
Was wir gerade beobachtet haben, war, ich habe jetzt
das Ding aufgerufen und hier steht als Typ Void.
Das heißt, diese Prozedur liefert kein Ergebnis.
Sie tut natürlich was. Da muss man aufpassen.
Also kein Ergebnis liefern heißt nicht, da passiert nichts.
Sondern das heißt nur, es wird mir kein direktes Ergebnis zurückgeliefert.
Also ich kann jetzt hier einen Zahn aufrufen und nochmal 20 einzahlen.
Und dann ist der Aufruf zu Ende. Während,
wenn ich jetzt Gibsaldo aufrufe, dann muss ich keinen Parameter angeben,
parrameterlos, deswegen kann ich es direkt aufrufen.
Aber jetzt kommt hier so ein Ergebnis. Hier kommt wirklich
so ein Fenster, wo gesagt wird, aha,
ich habe jetzt hier ein Ergebnis.
Da wird wirklich ein Wert geliefert. 140 zum Beispiel
in diesem Fall
Und dann muss ich das erst schließen. Und das ist tatsächlich genauso,
wenn ich jetzt hier sage, Giro kommt 1.gib Saldo.
Ja, dann kann ich das hier einfach aufrufen.
Kommt 140 raus und ich kann mir eine Variable NI deklarieren.
Ja, genau. Und dann frage ich mal,
was hat ihr für einen Wert? Ihr habt den Wert null.
Und jetzt sage ich, I ist gleich Giro Cont 1 gibt.
Saldo. Und dann wird tatsächlich Das Ergebnis von diesem Aufruf
gibt Saldo in dieser Variablen I abgespeichert.
Kann ich also hier tatsächlich so machen. Und dann siehe da,
I hat dann nicht mehr null, sondern da ist jetzt 140 drin.
Das ist eine Ergebnisprozesse. Wir nennen die halt Ergebnisprozeduren,
weil in der Objektorientierung die Dinger erstmal nur so syntaktisch aussehen,
dass sie statt Voyed irgendeinen Typ als Ergebnis haben.
Sie sagen, ich liefe einem in oder ich liefer
einen String oder was auch immer da als Ergebnis zurückkommt.
Das garantiert aber noch nicht, dass sie nicht trotzdem irgendwie
den Zustand des Objektes, das da gerade aufrufen wird, ändern.
Und wenn man so mathematisch versiert ist,
dann weiß man, Funktionen sind eigentlich, ändern nichts.
Funktionen sind irgendwie, was, die berechnen was,
aber die verändern nicht irgendwelche Zustände. Deswegen haben wir gesagt,
wir wollen diese Dinger nicht Funktionen nennen, sondern nur die Dinge,
die wirklich keine Zustände verändern, die nennen wir Funktionen.
Und die dann auch so ein Ergebnis liefern.
Aber die Dinger nennen wir halt Ergebnisprozeduren und das sind genau
die Methoden, die ein Ergebnistyp ungleich Void haben.
So, und da kann man tatsächlich Informationen an den Aufrufer
direkt zurückgeben. Und das ist jetzt hier nochmal dieses Beispiel,
also auch Maximum ist so eine,
eine solche Ergebnisprozedur liefert hier also ein, definiert ein Ergebnistyp,
Und an dieser Stelle steht dann hier tatsächlich Return Max.
Da wird jetzt festgelegt, welcher Wert wird denn an den Aufrufer gegeben?
Und dann kann tatsächlich an der aufrufenden Stelle das hier
stellvertretend genommen werden für das, was da berechnet wird.
Da wird also in Maximum irgendwas berechnet,
jetzt hier nicht sonders aufwendig, aber da kann ja auch mehr passieren.
Und das, was da zurückkommt, kann dann hier weiterverwendet werden. Okay,
ein Ergebnisprozedur, also irgendeine Prozedur,
die einen oder eine Methode auch in Java,
die hier einen Typ hat, ungleich wollt, da muss im Rumpf ein solches Return stehen.
Wenn das nicht da steht, gibt es einen Fehler
Okay. Was wir uns jetzt auch noch angucken sollten,
ist den Kontrollschluss. Er war jetzt erstmal, gab es
noch Fragen zu diesen Parametergeschichten aktuell, formal und so.
Ich glaube, das ist soweit bei allen ganz gut angekommen.
Sehr schön. Jetzt habe ich ja schon irgendwann gleich, glaube ich,
in der ersten Vorlesung was erzählt, über den Kontrollfluss.
Ich stelle mir das immer so vor wie so ein roter Faden,
der sich so durch die ganzen Objekte zieht,
die so in so einem Objekt intelligen System beteiligt sind.
Eine Methode nach der anderen aufgerufen,
da werden dann die Methoden abgearbeitet,
dann wird ein neuer aufgerufen und so
Das muss man sich schon auch nochmal sehr, sehr explizit
klar machen, was da passiert. Es ist tatsächlich so,
in der objektorientierten Programmierung, wir können es ja hier nochmal zeigen,
ich zeige nochmal den Zeichner und ich setze mal wieder einen Haltepunkt hier in Zeichenhäuser,
an diesem Punkt in der Methode,
sage ich jetzt einen Haltepunkt,
setze ich da hin und jetzt kann ich ja wieder den Debugger benutzen,
ganz kurz das Ding hier
ein bisschen kleiner machen
Ja. Und wenn ich jetzt das Ding schließe und hier den Zeichner aufrufe und sage,
ach ne, ich habe ja schon einen,
dann kann ich den ja direkt benutzen, sag mal, zeichne Häuser.
So, jetzt haben wir genau diese Situation,
jetzt bin ich, habe ich als Klient interaktiv Zeichenhäuser aufgerufen.
Wir sind jetzt tatsächlich hier angehalten, an dieser Stelle,
wo der Haltepunkt steht. Das heißt,
der Debugger zeigt jetzt hier genau diese Situation, ja,
das ganze Zeug brauchen wir nicht,
weil der Zeichner hat keine statischen Varianten, keine Instanzvarialen.
So, und jetzt sehen wir hier,
das Zeichen der Sonne aufgerufen wird
Jetzt können wir einfach Schritt übermachen, dann wird sozusagen
dieses Zeichen der Sonne komplett ausgeführt. Das kann ich jetzt
mal machen. Dann haben wir hier tatsächlich Zeichen der Sonne,
dann müsste ich jetzt hier irgendwo auf der Leinwand die nächste Sonne auftauchen.
Wir haben jetzt schon drei Sonnen. Das ist wie
im Science-Fiction-Film. Und jetzt ist es aber ganz spannend.
Jetzt steht hier dieser gelbe Balken, da an der nächsten
Zeile im Quelltext, wo etwas passiert.
Und jetzt kann ich hier ja wieder sagen Schritt über.
Und dann würde dieses Zeichenhaus komplett ausgeführt.
Kann ich mal machen. Zack, dann wird also
ein ganzes Haus gezeichnet
Jetzt haben wir hier den Balken an der nächsten Stelle.
Jetzt kann ich aber mal alternativ, statt das einfach
komplett auszuführen, kann ich auch in den Rumpf hineinspringen.
Das heißt, was ja passiert ist, dass ich hier
ein Zeichen nach Haus ja runterspringe im Kontrollfluss, ins Zeichen Haus.
Und jetzt mache ich hier mal einen Schritt hinein.
Und dann sind wir tatsächlich plötzlich in Zeichen nach Haus.
Und wenn ich jetzt hier noch mal in Zeichen eine Wand reinspringe,
Zeichen der Wand ist ja auch eine Methode, wo eine Wand gezeichnet wird,
dann kann ich da auch noch mal jetzt tatsächlich mit Schritt hinein hineinspringen.
Und dann bin ich tatsächlich jetzt hier da an der Stelle,
die ihr schon gesehen habt,
wie so
eine Wand gezeichnet wird
Quadrat angelegt, da wird die Farbe geändert und vertikal bewegt und so weiter.
Und hier kann ich jetzt, könnte ich jetzt auch reinspringen,
aber das ist dann nicht so spannend, so ein Konstrukteaufruf oder ähnliches.
Aber ich kann jetzt hier genau Schritt für Schritt das da ausführen lassen.
Und dann wird hier irgendwie die Wand sichtbar gemacht und dann ist sie da.
So. Und dann, wenn ich jetzt einen weiteren Schritt mache,
springe ich wieder genau dahin zurück, wo ich herkam.
Ich habe hier Zeichen, eine Wand wurde aufgerufen, irgendwo in, ich vermute in Zeichenhaus.
Und jetzt sind wir sozusagen dahin zurückgesprungen. Das heißt also,
das ist ganz wichtig, wenn man das verstehen will,
wie das funktioniert, dass das hier tatsächlich ja irgendwo sich gemerkt werden muss,
ich war zuerst in der Methode,
dann bin ich weiter gesprungen in die nächste und dann in die nächste,
welcher mit der fertig bin, muss ich ja wissen,
wo ich während ich wieder zurückspringen muss.
Und dafür gibt es tatsächlich hier dann eine Logik,
wie das passiert, das ist ja so eine Aufruffolge,
man sieht hier Zeichnerhaus, Zeichnerhäuser wurde als erstes aufgerufen,
dann zeichne Haus und jetzt kann man hier nochmal Schritt hinein machen,
dann ist man wieder hier, zeichne Dach.
Und man kann sich tatsächlich angucken, auch in Blue Jay,
an welcher Stelle stehen wir denn gerade in dieser anderen Methode?
Also ich habe mit dem Ziel gerade in Zeichne Dach,
ich kann es aber auch hier auch auf Zeichnerhaus klicken,
Und dann wird mir angezeigt,
Aran, da bin ich gerade an der Stelle.
Da ist der Kontrollfluss gerade reingeflossen, oder in Zeichnerhäuser.
Haben wir jetzt gerade, sind wir gerade dabei,
das zweite Haus zu zeichnen. Da stehen wir jetzt gerade
sozusagen und warten darauf, dass der Aufruf wieder zurückkommt.
Und dann kann ich aber auch einfach hier sagen,
fortsetzen und dann werden hier die ganzen Häuser gezeichnet.
Und dann ist alles passiert. Und das ist ganz wichtig.
Also beim Aufrufwechsel die Kontrolle vom Rufer zu der gerufenen Prozedur,
dann werden diese Werte der aktuellen Parameter an die formalen gebunden,
so wird das auch genannt.
Also es wird einfach, die werden darüber kopiert,
die werden ihnen zugewiesen
Prozeduren können geschachtelt aufgerufen werden, haben wir gesehen.
Also ich habe tatsächlich jetzt mehrfach geschachtelt. Dabei wird der Rufer unterbrochen,
sodass die Kontrolle immer nur bei einer Prozedur ist.
Es entsteht eine Aufrufkette. Also der tatsächliche aktuelle Anweisung ist
immer in dem aktuellen Objekt, das gerade ausgeführt wird.
Nach der Abarbeitung der Prozedur kehrt die Kontrolle zum Rufer zurück.
Das ist hier auch noch mal ein bisschen auf der Folie
veranschaulicht, haben wir jetzt ja mehr oder wieder gesehen.
Ein komischer Quelltext hier, If-Werte gegeben,
dann Volumen ist gleich berechne irgendwas hier.
So, und jetzt nehmen wir mal an,
Werte sind gegeben
Dann geht er genau hier rein. Und dann steht hier
so ein Prozeduraufruf. Und dann muss es irgendwo eine prozedure
Definition geben. Also eine Stelle irgendwo in unseren Quelltexten,
wo dann wirklich diese Prozedur beschrieben ist.
Ja, und dann kann man sich das vorstellen,
da wird da einfach reingesprungen in den Rumpf.
Dann wird das sequenziell ausgeführt. Und dann wird der Wehr zurückgeliefert,
irgendwie Return Result und wird dann hier in dieses Volumen 1 reingeschrieben.
Ja, und dann wird hier weiter ausgeführt,
das Else trifft jetzt nicht zu, also kommen wir hier dran vorbei.
Und das ist das, was wir den Kontrollfluss nennen.
Und das ist halt auch ganz zentral,
dass wir diesen Mechanismus versteht,
dass da bei Methoden aufrufen all das passiert
Okay, ich habe jetzt gesagt,
Prozeduren und Methoden ist eigentlich fast das Gleiche.
Alles das, was eine Prozedur kann, kann eine Methode auch.
Also die Methoden in Java können all das, also Parameterübergabe,
Kontrollfluss, Wechsel, lokale Variablen und so weiter.
Darüber hinaus haben aber diese Methoden,
die ihr ja hier in der Objektorientierung in Java mit Java kennenlernt,
noch so ein paar weitere Eigenschaften.
Erstens ist es so, dass eine Methode immer zu einem Objekt gehört.
Es gibt nicht so etwas wie freistehende Methoden.
In der imperativen Programmierung gibt es einfach Prozeduren und das
ist einfach so eine Sammlung von Prozeduren.
So ein Programm besteht aus einer Menge von Prozeduren
In der Black-Dorientierung ist es anders. In Java besteht ein
objektives System aus einer Menge von Objekten. Und die Objekte
hofen gegenseitig ihre Methoden auf und die Methoden hängen aber immer an Objekten dran.
Es gibt keine freischwebenden Methoden. Das ist ganz wichtig.
Und eine Methode kann immer auf die Felder des zugehörigen Objektes zugreifen.
Jetzt ist es so, dass ihr,
ihren Übungen haben wir schon so von den Betreuern so ein bisschen mitbekommen,
dass einige von euch, als sie diesen Zeichner da erweitert haben,
Variablen eingeführt haben.
Aber diese Variablen waren dann keine lokalen Variablen. Also hier in
der Klasse Zeichner hat man man ja sowas wie hier zum Beispiel oder bei hier,
da ist lokale Variable, da haben dann viele ihre Variablen,
die sie verwenden wollten, in dem Rumpf von der Methode,
haben sie irgendwo hier oben als Exemplarvariable deklariert.
Das funktioniert, ist aber irgendwie komisch, weil diese Variablen
werden ja nur gebraucht für die Dienstleistung innerhalb einer Methode.
Die gehören nicht zum Zustand eines Zeichners.
Der Zeichner hat gar keinen Zustand. Ich habe mich,
glaube ich, letzte Woche auch schon gezeigt,
wenn ich hier mal so ein Zeichnerexemplar mir angucke,
dann hat er einfach keine Attribute.
Die heißen halt jetzt in Blue Jay
heißen die Attribute
Keine Exemplarvariablen, keine Zustandsfelder. Und ihr solltet da auch nicht irgendwelche definieren,
weil so ein Zeichner, es sei denn,
ihr wollt, dass der Zeichner einen Zustand bekommt.
Okay. Und diese Methoden haben eine Sichtbarkeit,
das ist auch ein sehr zentrales Konzept in der Objektorientierung,
die, die public sind, gehören zur Schnittstelle,
ein Klient kann sie aufrufen, die E-Private sind,
die sind so eine Privatsache der Klasse.
Okay. Was wir auch kennengelernt haben,
um das jetzt nochmal so ein bisschen hier abzuschließen,
das ganze Thema so Prozeduren und Parameter.
Wir haben auch drei Arten von Variablen kennengelernt.
Die erste Art von Variablen, die ihr kennengelernt habt,
waren die lokalen Variablen. Da habt ihr in dem Quelltext
von diesem Zeichner irgendwie diese lokalen Variablen gesehen.
Dann habt ihr irgendwie auch Exemplarvariablen gesehen,
die haben wir aber noch nicht wirklich benutzt.
Einige von euch haben die, wie gesagt,
aus Versehen benutzt, aber es hat nicht so richtig funktioniert.
Und dann gibt es auch noch formale Parameter.
Und formale Parameter werden auch als Variablen angesehen. Was haben
die alle gemeinsam? Naja, sie sehen genauso aus.
Typ und Name. Alle diese Dinge haben einen Typ und
einen Namen. Also an dem Beispiel hier,
klasse Girokonto, ein Exemplarvariabel hat einen Typ und einen Namen
Oder hier der formale Parameter von Einzahlen, hat einen Typ
und einen Namen. Und auch diese lokale Variable hier,
die hier nur zur Verdeutlichung eingeführt ist,
hat einen Typ und einen Namen.
Und das sind aber drei verschiedene Arten von Variablen,
die auch unterschiedlich behandelt werden vom Compiler.
Und das werden wir uns auch noch mal ein bisschen ausführlicher angucken.
Nur, dass wir uns das erstmal klar ist, dass es die gibt.
So, also, und jetzt nochmal alles zusammengefasst.
Wir haben in der Objektorientierung immer dieses Verhältnisklient,
nimmt in Anspruch
einen Dienstleister
Objekte rufen Objekte auf. Wir haben jetzt in Thru ein
bisschen genauer hingehört, habe mir festgestellt, okay,
eigentlich ruft eine Methode eines Objektes die Methode eines anderen Objektes auf.
Also hier ruft Methode auf. Das heißt,
das ist hier dann der Aufrufer, der Klient.
Und da wird hier eine Methode aufgerufen. Methode können wir auch
Prozedur nennen. So, und der Aufrufer will natürlich wissen,
was die Methoden genau tun. Und damit er das weiß,
sollte der Dienstleister seine Methoden auch für die Klienten beschreiben.
Deswegen ist es sinnvoll, dass man da einen Kommentar schreibt,
was leistet denn meine Methode?
Und das sind natürlich hier jetzt auch die Methoden,
die an der Schnittstelle liegen, also für einen Klienten auch aufrufbar sind.
So, und jetzt macht der Aufrufer irgendetwas,
das heißt, er übergibt aktuelle Parameter.
Die aktuellen Parameter, die stehen immer beim Aufrufer,
in den konkreten Methoden aufrufen. Das sind echte Werte,
Literale wie 100 oder blau in Anführungsstrichen, oder variablen Belegungen,
also wenn ich da eine Variable angebe als aktuellen Parameter,
dann wird nur die Belegung dieser Variablen übergeben
Ja, und auf der anderen Seite, da kommen dann
die Dinger an, werden in formale Parameter reingestopft.
Und die werden im Kopf einer Methode deklariert,
die haben Typ und Name, das sind eigentlich Platzhalter,
die können unterschiedliche Werte annehmen, je nachdem,
wer das mit welchen Werten aufruft.
Und erhalten immer nur Kopien von dem, was da übergeben wird.
Das ist zentral. Ein Dienstleister kann einen Zustand haben,
das gucken wir uns nochmal ein bisschen ausführlicher an in den nächsten Wochen.
Und dieser Zustand wird dann in Zustandsfeldern gehalten.
Manche nennen es auch Attribute, manche nennt es Felder,
manche nennen es Exemplarvariablen,
wie auch immer
Ihr solltet diese Kernkonzepte alle gut im Kopf haben,
wie die dann benannt werden.
Das ist nur, damit ihr besser drüber reden könnt.
Gut, das nochmal, das Zwischenergebnis ist, ja.
Ja. Ja, von Kiel geht das auch für Objekte,
wenn man die ab und zu mal liebt.
Die Frage, die ihr stellt, lautet,
gilt das mit den Kopien auch für Objekte?
Wenn Objekte übergeben werden. Das ist eine sehr gute Frage.
Und es ist auf jeden Fall richtig, dass auch,
wenn man Objekte übergibt, nur Kopien übergeben werden.
Aber man übergibt keine Objekte in Java,
sondern man übergibt nur Referenzen auf Objekte
Und das kommt sehr ausführlich in der übernächsten Woche dran.
Also Referenzen werden wir noch sehr genau uns ansehen,
aber die werden auch nur als Kopien übergeben.
Es werden immer nur Referenzen kopiert. Die Parameterübergabe ist immer per Kopie.
Das könnt ihr mir glauben. Was dann passiert ist,
ich möchte einem Objekt Zugriff auf ein anderes Objekt geben,
dann übergebe ich eine Referenz. Und dann ist es
dasselbe Objekt, aber es ist eine Kopie der Referenz.
Aber das war schon eine etwas fortgeschrittene Frage.
Sonst noch Fragen zu dem, was ich jetzt hier
gerade gezeigt habe
Okay, dann habe ich das hier nochmal alles zusammengefasst.
Ich glaube, das könnt ihr auch einfach nachlesen im Skript.
Habe ich auch, glaube ich, jetzt alles mehrfach gesagt.
Spannender ist sowas hier. Juhu. Sturesi. Ja,
jetzt, ich habe euch ja wieder was erzählt,
ist ja alles so klar von mir erklärt worden,
dass jetzt eigentlich alle sofort richtig beantworten könnt.
Ihr habt hier diese Klassendefinition, die Klasse A. Und die
hat eine Methode M. Ja, und den Rest könnt ihr
einfach mal lesen. Könnt ihr euch das mal angucken.
Und ich habe dann da auch eine ziemlich schlaue Frage dazu.
So. Wie viele aktuelle Parameter enthält die Methode M?
Ich starte mal die Abstimmung und jetzt könnt ihr hier eure Stimmen abgeben.
Ihr seht da was, was ihr gar nicht kennt.
System-Out-Print, System-Out-Printeln. Ihr müsst vielleicht dann auch,
das müsst ihr auch lernen, wenn ihr so Quelltexte lest,
das, was ihr kennt,
das müsst ihr identifizieren und das andere müsst ihr vielleicht
erstmal ausblenden
Aber ihr seht, was hier passiert. Das ist also
eine Ergebnisprozedur. Ja, die liefert irgendein Ergebnis. So,
und jetzt einfach die Frage, sind das hier A ein?
Ist da ein aktueller Parampel drin? Zwei, drei oder vier
aktuelle Parameter. Super, wir haben schon 200 Stimmen zusammen.
Ich halte das mal an. Wir gucken mal,
wie so die Verteilung ist. Okay, ihr seht,
das ist jetzt ein sehr spannendes Ergebnis. Jetzt kommen wir langsam in die Ecke,
wo ich dann merke, dass diese Storési-Fragen einfach sehr sinnvoll sind,
weil ich kann euch, ich muss euch leider sagen,
dass die Mehrzahl von euch falsch liegt.
Die richtige Antwort ist nämlich, es sind zwei.
So, großes Entsetzen. Nur 20 Prozent von euch haben das jetzt richtig.
Warum? Ihr wollt wahrscheinlich wissen, warum, oder?
Ich könnte es nach der Pause auflösen oder sofort.
Nein, also ganz einfach, das hier ist ein Kopf
einer Methode und da stehen formale Parameter
Formale Parameter. Diese Methode hat drei formale Parameter.
Dann stehen hier zwei Methoden Aufrufe. In runden Klammern sieht
man immer, da sind die Parameterlisten. Hier wird eins
dringend übergeben. Also ist das der erste aktuelle Parameter.
Hier wird irgendwie A plus B plus C übergeben.
Was immer A, B und C ist, es sind Ins.
Also wird hier irgendwie ein Int berechnet und der wird dann übergeben.
Das ist der zweite aktuelle Parameter. Das sind die
aktuellen Parameter, die an Methoden Aufrufstellen übergeben werden.
Also sind es zwei
Und das ist nichts, was sie nicht wissen konntet,
weil ich habe es ja vorher erzählt. Also das nur einfach so,
obwohl ich alles hier so, hoffe ich,
klar zu erklären, ist das eben halt nicht selbstverständlich,
dass ihr das alles sofort versteht.
Ihr müsst das halt üben und müsst diese Begriffe mal wieder angucken.
Okay, dann würde ich jetzt sagen, machen wir mal
in 5 Minuten Pause. Jetzt geht es um Klassendefinitionen.
Wir kommen jetzt nochmal Klassendefinitionen etwas genauer an. Und kommen
vor allen Dingen darauf, wie die denn syntaktisch aufgebaut sind.
Und da geht es eben tatsächlich dann um den Begriff Syntax,
den ihr in eurem Studium wahrscheinlich noch ein paar Mal begegnen werdet.
Also, eine Klassendefinition. Das, was wir hier bisher
gesehen haben, ist lediglich eine textuelle Beschreibung einer Klasse.
Sie liegt in einer Textdatei und kann mit einem Editor bearbeitet werden.
Das ist vielleicht noch mal was, was man hier noch mal zeigen kann.
Ich habe ja hier in diesem Projekt, zum Beispiel,
na nehmen wir mal lieber das andere Projekt hier, Girokonto, da habe ich eine Klasse Girokonto.
Und das hier ist die Klassendefinition dazu. Das ist der Quelltext. Und ihr könnt euch das wirklich vorstellen,
dass so vorstellen, dass dieser Quelltext, nichts weiteres,
dass eine ganz lange Sequenz von Zeichen,
also hier ist zum Beispiel erstmal ein Schrägstrich,
dann ist da ein Stern, das ist dann noch ein Stern,
dann ist da ein Zeilenumbruch, ist da wieder ein Lehrzeichen,
dann ist da ein Stern und so weiter.
Und das heißt, von links oben bis rechts unten,
da hast du es hier zweidimensional dargestellt,
aber das muss es ja nicht so sein.
Es ist tatsächlich sequentiell in einer langen Zeichenkette abgelegt.
So kann man sich das vorstellen.
Und die Dinger liegen tatsächlich einfach im Dateisystem. Das heißt,
wenn wir hier einfach mal ins Dings gehen,
wo haben wir es denn hier, da?
Da Girokonten, dann ist das ein Verzeichnis.
Ja, hier gibt es ein Girokonto.jawa. Hier gibt es
ein Girokonto.ccctxt, das ist was, was BlueJ benutzt.
Und Girokonto.klaas. Und dieses Ding hier, das kann ich
einfach auch öffnen mit einem Editor zum Beispiel mit Word Pad.
Dann habe ich hier irgendeinen Editor hergenommen, der diesen Text einfach bearbeitet.
Das ist der gleiche Text, der ihn jetzt auch Blue Jam mir anzeigt,
im Editor und das Ding ist hier jetzt genauso bearbeitbar.
Aber es ist natürlich nicht so schön mit Syntax-Highlighting,
weil, und das ist immer ganz wichtig,
so eine Folge von Zeichen hat erstmal ja für sich genommen keine Bedeutung.
Erst wenn ich einem einer Java-IDE,
wie Blue Jay sage, das ist jetzt übrigens Java-Quelltext,
dann fängt Blue Jay an zu sagen, oh,
damit kann ich ja mal so ein paar Sachen farblich hervorheben,
weil das ist ja eine Methode und das ist ja
ein Feld und so weiter
Also das ist ganz wichtig. Wenn wir eine Klasse benutzen wollen,
dann muss die in eine, von dieser menschenlesbare Klassendefinition,
das ist ja was, was wir schreiben.
Wir schreiben Klassendefinition, deswegen ist es in einer Form geschrieben,
die wir ganz gut lesen und schreiben können.
Und das muss aber übersetzt werden in etwas, was der Computer wirklich ausführen kann.
Das nennen wir übersetzen beziehungsweise kompilieren. Das habt ihr auch schon gesehen,
wenn in Bluejoy diese Klassensymbole so gestreift sind,
dann heißt das, der Quelltext ist noch nicht übersetzt,
die Klassendefinition ist noch nicht übersetzt.
Und nur durch eine korrekt übersetzte Klassendefinition entsteht eine Klasse,
die bei der Ausführung dann tatsächlich für die Erzeugung von Exemplaren
benutzt werden kann
Also tatsächlich muss hier so eine Girokonto.claas-Datei sein,
damit man überhaupt irgendetwas machen kann,
damit tatsächlich in Blue Jay ich jetzt hier sagen kann,
mach mir mal ein neues Girokonto.
Okay. Okay. Kleiner Ausflug. Nur ganz kurz.
Es gibt verschiedene Arten von Programmiersprachen, habe ich jetzt schon an verschiedenen Ecken angedeutet.
Es gibt Programmiersprachen, die sind reine Compilersprachen,
sowie CPlus Plus oder Modler 2, Pascal früher.
Da werden die Anweisungen, die man so hinschreibt,
einmal übersetzt in Maschinensprache und dann direkt auf einer Rechnerarchitektur ausgeführt
Es gibt aber auch so was wie Interpretersprachen,
da wird sozusagen nicht einmalig der Quelltext übersetzt und dann das Kompilat ausgeführt,
sondern da wird tatsächlich immer Zeile für Zeile,
wird wieder neu interpretiert.
Da gibt es einen Interpreter, der jede Zeile hernimmt,
in Klartext, wie wir ihn schreiben, das interpretiert und dann ausführt.
Liz hat das gemacht oder macht das. Und da gibt
es so hybride Sprachen wie Jaba und C. Sharp,
die machen das so, dass sie in eine Zwischensprache übersetzen.
Also diese Punkt Klaas-Datei, die ihr hier im Dateisystem liegen seht,
die ist eine Art Zwischensprache, Und die ist tatsächlich aber universell.
Das heißt, diese Class-Datei könnte ich auch auf einen Macintosh zum Ausführen bringen.
Oder auf einem Ubuntu-System. Das muss kein Windows-System sein.
Das ist tatsächlich, diese Class-Datei ist überall ausführbar.
Ich kann mal zeigen, wie die so aussieht.
Ich kann einfach hier mal so einen Doppelklick drauf machen.
Dann sagt er mir, uh, kann ja nichts mit anfangen.
Jetzt sage ich, Programm aus einer Liste,
einer installiert, nehme ich mal irgendwas hier.
Wordpad meinetwegen, aber bitte nicht immer. So. Und dann sieht das
so aus. Also man sieht hier, das ist relativ kryptisch.
Das liegt daran, dass der Editor jetzt versucht,
Binärdaten irgendwie darzustellen als Zeichen auf dem Bildschirm.
Da kommt natürlich nichts Sinnvolles bei raus. Das ist einfach Kraut und Rüben,
weil die Struktur ist eine ganz andere als, das ist also nicht zeichenorientiert.
Aber man sieht das in so einer Klaas-Datei auch so ein paar Dinge drinstehen.
Hier stehen im Klartext dann doch so Dinge wie Anfang Saldo,
Einzahlen, Gipsaldo, also irgendwo sind da diese Dinge noch im Plattext abgelegt,
in so einer Klaas-Datei.
Aber das ist nur so am Rande interessant.
Das ist aber genau das Prinzip in Java.
Quelltext wird übersetzt in Zwischencode, in den Bytecode.
Und der wird dann, damit er ausgeführt werden kann,
an die Java Virtual Machine übergeben
Das ist tatsächlich so, diese Java Virtual Machine ist ein Interpreter,
die interpretiert diese.clas-Dateien. Und dann kann man wirklich Programme
damit ausführen. Warum haben die das gemacht? Naja,
die hatten mit Java damals eine ganz coole Idee,
die haben gesagt, wir machen diese Zwischensprache,
können also jedes Java-Programm in diese Zwischensprache übersetzen.
Und dieses Zeug ist dann auf jeder Plattform ausführbar,
auf der ein solcher Interpreter ist.
Also so eine Virtual Machine. Überall,
wo man eine Java Virtual Machine hat,
kann man auch Java-Programme ausfüllen,
und zwar übersetzte Java-Programme,
diese Clas-Dateien
Und das ist die Grundidee von Java gewesen, von Anfang an, Bright Once Run Anywhere.
Also einmal schreiben und auch übersetzen und dann kann man das überall ausführen.
Man muss halt nur überall eine Virtual Machine haben. Das ist ein ziemlich cooles Konzept,
das ist sozusagen genau das Gegenteil von.net, bei.net,
in Microsoft, die haben auch sowas wie eine Zwischensprache eingeführt,
aber die haben das nur gemacht,
damit möglichst viele verschiedene Programmiersprachen auf der Windows-Plattform laufen können.
Das heißt, eigentlich ist es primär für Windows gemacht worden.net,
damit sozusagen auch so eine Art Bytecode auf dieser Witchle-Machine
ausgeführt werden kann,
aber von
ganz verschiedenen Programmiersprachen wird
Übersetzt. Also viele Programmiersprachen, eine Plattform bei Java, eine Programmiersprache auf vielen Plattformen.
Okay. Das ist also alles nur Software, diese Virtual Machines,
die interpretieren ja diesen Bicode und führen den dann auf dem entsprechenden Rechner,
auf der Mac-and-Tosh-Architektur oder auf der Windows oder auf der
was weiß ich, Architektur aus.
Und ihr wisst ja, in fast jedem elektronischen Gerät steckt heutzutage eine Java Virtual Machine drin.
Jeder Toaster spricht heute Java. Und das sind dann auch
relativ einfache Maschinen. Hauptsache, die haben eine Virtual Machine.
Dann kann man da Java ausführen. Das ist schon faszinierend. Und die haben eigentlich sozusagen,
die bilden so eine Art Kapsel um die von Neumann-Architektur,
die in jedem Rechner drinsteckt,
die aber dann sehe ich sehr unterschiedlich gestaltet,
wenn ich einen früheren Power-PC hatte als Prozessor und das mit einem Intel-Prozessor,
dass man einfach verschiedener Befehlssatz und das wurde dann von den Virtual-Machines weggekapselt.
So, und jetzt kommen wir zu der syntaktischen Struktur von Klassendefinitionen.
Und das kennt ihr auch aus dem Deutschunterricht und vermutlich auch aus Fremdsprachunterricht,
dass es sowas gibt wie die Syntax einer Sprache.
Also es gibt Syntaxregeln, Grammatikregeln und so etwas gibt es
eben halt auch für Programmiersprachen und Die ist ziemlich formal.
Also diese Syntax von Programmiersprachen ist sehr, sehr formal beschreibbar.
Und das dient eigentlich zwei Zwecken. Zum einen, Menschen sollen
es lesen können. Diese Syntax muss irgendwie so gut lesbar sein,
dass Menschen, weil wir müssen letztendlich hier die Programme schreiben.
Darum kommen wir nicht drum rum. Automatische Programmierung ist immer
wieder versprochen worden von der KI, von der künstlichen Intelligenz.
Aber das gibt es noch nicht. Wir müssen immer noch
selbst entscheiden, was unsere Programme können sollen.
Und deswegen müssen wir sie lesen können.
Aber Computer müssen sie auch lesen können. Und Computer sind
ziemlich blöd. Die sind unglaublich schnell, aber blöd.
Und die müssen die eben halt auch lesen können.
Deswegen muss das sehr, sehr genau sich an diese Syntaxregeln
halten, was wir da so schreiben
Und es gibt so sehr gebräuchliche Darstellungsformen für die Syntax von Programmiersprachen,
nämlich einmal die erweiterte Backos-Nauerform, die gucken wir uns an.
Die ist sehr weit verbreitet für die Beschreibung von der Syntax von Programmiersprachen.
Und das gilt tatsächlich für alle Programmiersprachen, die es so gibt.
Es gibt, für viele Programmiersprachen gibt es solche EBNF-Darstellungen.
Syntax-Theorien bekommen wir uns auch noch an.
Erstmal muss ich noch so ein paar Begriffe ein bisschen erläutern,
Syntax, Semantik und Pragmatik. Die Syntax ist das,
was die Regeln enthält, nach denen wir unsere Sprachen aufbauen.
Gibt es auch für natürliche Sprache,
aber auch auch Programme sind nach diesen festen Syntaxregeln aufgebaut.
Was eigentlich wichtig ist, ist die Semantik. Das ist ein Begriff,
diese Begriffe Syntax-Semantik, Pragmatiken kommen aus der Semiotik,
also aus der Theorie der Wissenschaft, der Verarbeitung von Zeichen, Simiotik.
Und dann haben die halt diesen Begriff Semantik eingeführt.
Das heißt, das ist die Bedeutung dessen, was da steht.
Also wenn ihr so ein Programm hinschreibt, das kann syntaktisch korrekt sein,
ihr habt eben diese Storesi-Frage von mir gesehen,
da war irgendeine Klassendefinition, die war völlig sinnlos,
aber die war so taktisch korrekt, so ein taktisch okay,
aber die Semantik war Man weiß es nicht.
Die Semantik eines Programms ist das, was es wirklich tut,
was es im Speicher für Zellen verändert oder vielleicht auch über
den Speicher hinaus irgendwo Sensoren abfragt oder Aktuatoren steuert irgendwas.
Computer sind ja heutzutage mehr oder weniger bei der Steuerung von allen beteiligt.
Und Programmiersprachen definieren eben halt auch nicht nur Syntax-Regeln,
also so Regeln wie ein wohlgeformtes Programm aussieht,
sondern auch Semantik-Regeln, die zum Beispiel wir sagen,
dass Variablen immer deklariert werden müssen, bevor sie benutzt werden.
Die Dinger werden auch als Semantik-Regeln bezeichnet. Eigentlich sind das
irgendwie so Regeln über die einen Aufbau eines Programms,
die gar nicht so viel damit zu tun haben,
was das Ding tut.
Die heißen aber auch Semantik-Regeln. Aber merkt euch einfach,
Semantik ist das, was wirklich das Ding tut.
Die eigentliche spannende Sache an so einem Programm. Pragmatik ist auch
nochmal ein wichtiger Begriff. Das ist nämlich so der,
sagen wir mal, die Lehre vom Gebrauch einer Sprache.
Also wie sagt man das denn, wenn ich jetzt Italienisch lerne,
dann, ich will jetzt irgendwo ein Restaurant suchen,
dann kann ich halt was Korrektes, also syntaktisch korrekt sagen.
Auch die Semantik ist klar, aber dann die Art und Weise,
wie man das sagt,
kann trotzdem Leute beleidigen,
wenn ich sie falsch frage
Und diese Pragmatik ist ganz oft auch mal so durch
den Kontext geprägt und durch den Zweck.
Ich gebe mal ein paar Beispiele. Also, Syntax
einer Sprache ist so Grammatikregeln. Also zum Beispiel hier ein
deutscher Satz ist definiert als Subjekt, Prädikatobjekt, Punkt.
Eine Möglichkeit, wie ein deutscher Satz aussehen könnte.
Und da haben wir hier so ein Beispiel, das ist
ein syntaktisch korrekter Satz. Der Mann beißt den Hund. So,
wenn man nicht gerade ein Fan von John Irving ist und
gab und wie er die Welt sah, gelesen hat,
dann ist das erstmal komisch, dieser Satz.
Da ist die Semantik erstmal eigenartig. Normalerweise beißt der Hund
den Mann
Kann auch andersrum sein, aber wir können auch sagen,
das Haus streichelt den Mann.
Da wissen wir wirklich, das ist die Semantik sehr komisch.
Ist aber syntaktisch völlig in Ordnung. Das Haus streichelt den
Mann, subjektpräg, hart, aber Piak, wunderbar.
So ein taktisch, okay, Sinn, komisch.
Unterschied zwischen Semantik und Pragmatik, das ist auch so ein schönes Beispiel,
wenn ich jetzt sage, da ist die Tür.
Das kann so ein Hinweis sein, jemand fragt mich
ganz freundlich, wo ist denn hier die Tür?
Da sage ich, da ist die Tür. Oder
wenn mich jemand wahnsinnig aufregt und ich jetzt irgendwann sage,
jetzt reicht es mir, aber da ist die Tür,
dann heißt das so viel wie,
du gehst jetzt besser raus,
sonst dreht hier
die Gurgel um
Und das ist dann die Pragmatik. Das hängt also vom Kontext ab.
Und das ist einfach, die Semantik ist die gleiche,
da ist die Tür, die Aussage ist die gleiche.
Aber es hat dann unterschiedliche Wirkungen und unterschiedliche Pragmatik.
Benutzerhandbücher, wenn ihr sowas mal in die Finger kriegt,
die geben oft Hinweise zur Pragmatik.
Also so macht man das in der Software, die ihr
da gerade irgendwie jetzt benutzt. Alle Arten von Quelltextkonventionen,
die wir jetzt ja auch einführen in dem Übungsbetrieb,
also diese Woche oder nächste Woche spätestens,
werden wir euch Quelltextkonventionen vorgeben.
Und das sind auch Hinweise zur Pragmatik
Vielleicht noch mal hier an einem Beispiel in Java.
Hier haben wir jetzt Klaas Girokonto, das kennt ihr,
Saldo. Man sieht hier grün ein Feld, rot,
die Methode und optional Konstruktoren. Konstruktor haben wir hier nicht.
Das hier ist so eine Art einfache Syntaxbeschreibung. Also man kann sagen,
so eine Klassendefinition sieht so aus, übervereinfacht Klaas Klassenname,
dann ein Rumpf mit geschweiften Klammern und dann irgendwie optional Felderkonstruktoren, Methoden.
Zum Beispiel jetzt, wenn wir Semantik uns angucken,
Semantikregel von Java sagen, für die Klasse Girokonto,
wenn hier kein Konstruktor steht,
dann erzeugt der Compiler automatisch
einen Konstruktor
... Hast jemand Ersatz? Nee, und jetzt ist es
wieder da. Okay. Dass das immer ärgerlich bin.
Das Mikrofon ausfällt. Jetzt geht's wieder. Genau,
also wenn wir kein Konstrukt da hinschreiben,
wird aber trotzdem ein Konstrukt da erzeugt.
Der Compiler baut den da rein. Das ist eine Semantikregel
der Sprache von Java. Die sagt einfach,
das ist so. Jede Klasse hat einen Konstruktor.
Wenn ihr keinen hinschreibt, dann setze ich einen rein
Pragmatik ist tatsächlich die Sache der Reihenfolge. In den Quelltextkonventionen sagen wir,
es sollte immer so sein, zuerst die Felder,
dann die Konstrukte und dann die Methoden.
Das muss aber nicht so sein. Also die Syntax von,
also diese Reihenfolge, ihr könnt in Java auch die Felder
ganz nach unten schreiben und die Methoden ganz nach oben und die Konstrukteuren mitten rein,
ihr könnt die bunt durcheinander mischen.
Überhaupt kein Problem. Das ist so taktisch völlig in Ordnung.
Das ist also eine Konvention, gehört also zur Pragmatik,
dass man da eine gewisse Reihenfolge einhält.
Gut. So, und jetzt kommen wir auf etwas,
das ist sagen wir ein bisschen anstrengend. Ich hoffe mal,
dass ihr da jetzt noch ein bisschen Geduld mit ihr mit mir habt.
Es geht nämlich jetzt darum, wie man diese Syntax einer Programmiersprache denn formal beschreiben kann.
Diese formalen Grammatiken, die wir jetzt hier gleich kennenlernen,
werden, die bestehen aus Regeln mit den Wörtern,
also so Sätze, so eine Klassendefinition ist so ein Wort,
aus einem Staatssymbol gebildet werden.
Da gibt es einen theoretischen Hintergrund dazu,
das sind die sogenannten kontextfreien Grammatiken.
Und die werdet ihr in FGI 1
ausführlich euch ansehen
Und ich glaube, so mehr oder weniger alle von euch
müssen FG1 besuchen. Von daher ist das etwas,
was euch schon so ein bisschen hier vorab interessieren könnte.
Und eine konkrete Ausprägung von diesem kontextfreien Grammatiken ist die sogenannte Baccos-Nauer-Form.
Die ist irgendwann mal Mitte der 50er entwickelt worden von
John Baccos und Peter Nower.
Deswegen heißt die Baccos-Nauer-Form. Sehr kreativ. Also BNF.
Und das ist eine ziemlich häufige Form der Syntaxbeschreibung von Programmiersprachen.
Ganz wichtig, es gibt zwei zentrale Einheiten in diesem
formalen Grammatiken,
in dieser BNF
Es gibt Nicht-Terminale und Terminale. Oho, jetzt geht's wieder
los. Jetzt führe ich wieder Begriffe ein.
Und so taktische Variablen sind Nicht-Terminale und syntaktische Basiselemente,
Terminale, Symbole, die werden Terminale genannt.
Nicht-Terminale werden oft in Spitzenklammern notiert, also hier mal sowas wie eine Zuweisung.
Also wie sieht eine Zuweisung in einer bestimmten Programmiersprache aus?
Naja, da kann man eben halt eine Definition angeben und
sagen, hier, das ist definiert als.
Dieser Pfeil sagt mehr oder weniger so, ist eine Zuweisung definiert,
besteht aus einem Bezeichner, einem Zuweisungssymbol und einem Ausdruck.
Wobei diese Bezeichnung und Ausdruck anscheinend auch wieder Variablen sind.
Also so sind taktische Variablen
Und auf der linken Seite dieses Ableitungssymbols steht immer genau ein Lichtherminal.
Auf der rechten Seite kann dann beliebig viel Zeug stehen.
Zu jedem Nicht-Terminal muss es mindestens eine Regel geben,
weil wenn ich zum Beispiel jetzt hier eine Nicht-Terminal-Bezeichner habe,
dann möchte ich bitte auch eine Bildungsregel dafür haben,
mindestens eine, wo also Bezeichner auf der linken Seite steht,
damit ich weiß, wie sieht denn jetzt ein Bezeichner aus?
Okay, die Terminale sind dann, werden auch Lexime oder Token genannt,
das sind die reservierten Wörter in einer Programmiersprache, Bezeichner,
also Namen von Variablen, Literale,
sowas wie eins oder Anführungsstrichen blau und ähnliches.
Und Sonderzeichen, also so Operatoren, größer, kleiner und so weiter.
Die Terminale werden oft in diesen einfachen Anführungsstrichen angegeben, also hier.
Und die sind aus Sicht der Grammatik unteilbar. Das sind
sozusagen, das sind Atome, Atome in dieser Grammatik.
Okay, dann, wir sind gleich durch. Ja,
ein Staatssymbol gibt es, das ein Nicht-Terminal ist immer das Staatssymbol.
Von diesem Staatssymbol aus werden alle Wörter der Sprache abgeleitet.
Also alle Sätze oder eigentlich Wörter. Wenn ich also hier
als Staatssymbol Zuweisung habe, dann habe ich hier,
ich bezeichne gleich Ausdruck
Und dann kann es für solche syntaktischen Variablen, aber auch
mehrere Definitionen geben. Also zum Beispiel eine Zahl kann sein,
Intiger oder Reel, sind beides Terminale und ich kann sozusagen
Zahl entweder ersetzen durch Intiger oder durch Reel.
Das ist hier so ein logisches Oder. Also für die
Wahl zwischen alternativen Regeln. Und Nicht-Terminale können auch rekursiv definiert
sein, aber das ist ja hier ganz witzig.
Also Anweisungsfolge ist entweder eine Anweisung oder eine Anweisung,
erfolgt von einem Semikolon und einer Anweisungsfolge.
Und das kann ich dann wieder anwenden. Ich habe wieder
eine Regel für eine Anweisungsfolge und so weiter.
So kann ich also beliebig lange Anweisungsfolgen bauen
Wir machen mal ein Beispiel. Wir haben diese einfache Syntagsbeschreibung hier. Zuweisung ist,
wir zeichnen da gleich Ausdruck und dann habe ich hier irgendwie bezeichnet,
A, B, C. Also ein Bezeichner kann entweder A,
B oder C sein.
So, und dann habe ich hier einen Ausdruck,
rechts von diesem Zuweisungssymbol, das kann entweder Bezeichner Plusausdruck sein,
bezeichner Malausdruck oder ein geklammerter Ausdruck oder einfach nur ein Bezeichner.
Mehrere alternative Regeln. Durch schrittweises Ersetzen der Nicht-Terminale durch die
entsprechenden Definitionen kann ich dann sozusagen alle Wörter der Sprache generieren und
ich kann jetzt mal ein konkrete, eine konkrete Ableitung machen.
Also ich habe hier zum Beispiel Das Staatssymbol ist Zuweisung,
also gucke ich mir die eine Regel an und das ist Bezeichner, gleich Ausdruck.
So, dann habe ich noch eine Regel. Das habe
ich für Bezeichner, kann ich jetzt A oder B oder C einsetzen.
Ich nehme jetzt einfach mal irgendwas, zum Beispiel A.
Damit habe ich jetzt ja schon alles, was terminal ist,
wird nicht weiter ersetzt. Das ist sozusagen fertig.
Das habe ich hier noch einen Ausdruck. Na gut,
jetzt gucke ich mal, was gibt es in der Regel?
Gibt es eine Regel für Ausdruck? Ja,
hier steht Ausdruck auf der linken Seite,
gibt es mehrere Möglichkeiten, ich nehme mal irgendeine.
Zum Beispiel bezeichne mal Ausdruck. Also hier die zweite Regel.
Und dann ersetzt sich hier wieder den Bezeichner durch ein B
dann habe ich noch einen Ausdruck und dann nehme ich jetzt
noch mal was, was Geklammertes.
Nämlich hier mit Klamottenausdruck, so mit Zeichner Plus-Ausdruck,
dann wird das wieder ersetzt. Und so ersetze ich hier
nach und nach Nicht-Herminale durch terminale Symbole und am Ende
habe ich dann nur noch terminale Symbole.
Das heißt, ich habe jetzt einen Satz abgeleitet aus dieser Grammatik.
Das ist ein bisschen theoretisch. Ich weiß,
ich weiß, das ist ein bisschen theoretisch.
Das werdet ihr ein bisschen üben in den Übungen und wir
werden das auch noch mal ein bisschen uns näher ansehen.
Diese sogenannte, das ist eine Frage
Dauert die Schampfform, aber nur die ideale Sprachbeschreibung allgemein.
Er fragt etwas, das in der Bakkus-Nauerform nur linkslineare Sprachen beschrieben werden können.
Magst du mir beschreiben? Ich frage dich lieber nicht.
Ich möchte jetzt nicht, dass du den Leuten jetzt hier zumutest,
das zu thematisieren, was eine linkslineare Sprache ist.
Die Bakkus-Nauerform ist eingeschränkt in ihrer Mächtigkeit. Man kann bestimmte
Dinge damit nicht beschreiben. Syntax von Programmiersprachen lässt sich aber
ziemlich gut damit beschreiben. Also es geht jetzt gar nicht darum,
wie mächtig diese Sprachformen sind, sondern wir wollen ganz pragmatisch sehen,
die werden benutzt, um Programmiersprachen zu beschreiben.
Und wir wollen diese Notation verstehen. Bitte? Wird uns
noch so parallel ein bisschen machen.
Und ich betreibe es mit der Bank. Ja,
aber wie gesagt, momentan ist es erstmal nicht wichtig,
wie die Grenzen der Bank aus Neuen. Ich glaube,
hier sitzen 150 Leute, die wissen überhaupt nicht,
was die Bank aus Neuer Form ist und wollen erstmal die elementaren Konzepte verstehen,
bevor sie über die Grenzen der theoretischen Grenzen nachdenken.
Also ich glaube, das ist keine Frage,
die sich jetzt hier aufdenkt.
Aber wir können gerne nochmal drüber reden hinterher.
Also, jetzt haben wir diese Bakkos-Nauerform und die ist dann
erweitert worden in die erweiterte Bakkos-Nauerform, also relativ einfach.
Auch das ist relativ schnell verständlich. Eine Anweisungsfolge kann entweder
so definiert sein, Anweisungen oder eben halt hier rekursiv, blöd.
Einfacher ist es zu lesen, wir kommen jetzt immer dazu,
dass es einfach immer leichter wird für euch, das zu lesen.
Eine Anweisungsfolge ist definiert als eine Anweisung und dann sagen diese geschweiften Klammern,
beliebig oft kann das, was dazwischen steht, auftreten.
Oder das, was in eckigen Klammern steht,
kann genau einmal auftreten. Also entweder tritt es auf oder nicht
, ist also optional
Diese EBNF ist auch benutzt worden, um,
also hier in den Syntaxdiagrammen ist es nochmal eine andere Form,
wie man es darstellt. Eine Zuweisung sieht zum Beispiel so aus,
Bezeichner, Gleichausdruck oder bei einer Zahl Alternativen,
Intacher Real, da kann man auch ganz gut nachvollziehen,
dass zum Beispiel sowas wie, ich möchte eine Anweisungsfolge definieren,
dann kann ich mir vorstellen,
ich habe mehrere Anweisungen mit einem Simikolan getrennt,
dass ich hier sozusagen durch dieses Ding durchwiese und irgendwann hier so rausfließe.
Alles nicht so wichtig. Nee, schon wichtig.
Warum erzähle ich das? Und jetzt müsst ihr nochmal
ein paar Minuten für mich haben
Das ist ja jetzt hier kein Selbstzweck,
dass wir euch langweilen wollen, sondern wenn ihr euch die
Syntax von Java angucken wollt und die ist ja verfügbar hier,
es gibt es also im Internet gibt es die Sprachspezifikation von Java.
Die sieht so aus, ja, da gibt es also
tatsächlich im Web als Online-Version. Hier ist nur der Table
of Content und da scrolle ich mal eben so ein bisschen runter,
ja, weil das ist ziemlich viel Zeug.
Ja, okay. Ziemlich viel Zeug. Eigentlich möchte ich
nämlich hierhin zur Syntax. Es gibt die Syntax.
Da geht es sie. Und die Syntax sieht so aus
Das ist auch ziemlich viel Zeug. Die Sprache ist nämlich groß.
Und das sind jetzt, das ist auch in einer Art Baccous-Nauerform notiert.
Ihr könnt zum Beispiel hier sagen, eine Compilation-Unit,
also ein gesamtes Java-Programm mehr oder weniger oder eine Besetzungseinheit,
besteht aus Package. Und da kommen jetzt auch da Sachen,
die ihr gar nicht kennt und die auch gar nicht kennen müsst.
Denn wir haben für euch Java-Level 1 definiert, mit Baccous-Nauerform.
Und deswegen habe ich hier jetzt mal im Komsi,
wo ist denn das, kommen Sie hingeraten?
Da ist das Komsi. Da haben wir jetzt für euch
mal Aufgabenplatz 3 eine ganz kleine Syntax-Definition gebaut,
die aber auch schon ziemlich mächtig ist
Java-Level Syntax 1. Schade bei Level 1 Syntax. Das sieht so aus.
Okay, also hier kann ich jetzt einfach mal eben,
das ist die gesamte Syntax auf einer Seite.
Okay, es ist klein geschrieben, gebe ich zu.
Aber das ist deutlich weniger als das, was Java ausmacht.
Und hier habe ich nur mal ein Beispiel, wie eine Anweisung definiert.
Eine Anweisung in Java. Das ist ein Nicht-Terminal, ist definiert als.
Entweder ist es ein IF mit einem möglichen Ls oder es
ist eine Return-Anweisung, es ist eine leere Anweisung,
es kann eine Zuweisung sein,
es kann in einem Methodenaufruf sein oder es kann
ein Blog sein
Das einfach, dass ihr das mal seht.
Und das ist auch das, was wir hier auf
den Folien nochmal so ein bisschen dargestellt haben.
Also, Staatssymbol, Compilation Unit. Doppelpunkt stattdessen ist Ableitungssymbols.
Terminale in Blau, EBNF-Symbol in Rot. Hier nochmal Statement,
ein Nicht-Terminal mit sechs Alternativen, die auf einzelnen Zeilen stehen.
Also jede Alternative Möglichkeit, Staatssymbol abzuladen, steht auf einer eigenen Zeile.
Das könnt ihr euch im Skript nochmal angucken,
weil da habe ich nämlich ein bisschen mehr Zeug dazu gebaut,
dass ihr nochmal so an einem Beispiel seht,
wie so
eine Ableitung funktioniert
So, EBNF, Syntax, wir machen nochmal eine Verständnisfrage.
Ja, wir wollen nochmal so ein bisschen Storesi machen.
Also ich habe jetzt ja, ich gebe zu,
sehr schnell die Syntaxdefinitionen hier erklärt. Das Staatssymbol von
dieser EBNF sei Ausdruck. Es gibt also zwei Regeln,
einmal was ein Ausdruck ist und was eine Bezeichner ist.
Meine Frage dazu in Storesi. Wie viele verschiedene Ausdrücke definiert
diese Grammatik? Also wie viele verschiedene Wörter kann man jetzt
generieren aus dem Staatssymbol
Also wenn ich jetzt das Staatssymbol hinnehme und daraus jetzt alle Möglichkeiten,
alle möglichen Wörter ableiten will, wie viele wären das dann?
Drei, sechs, acht oder neun. So,
und ich hoffe, das ist jetzt,
er hat zumindest eine Idee davon, wie das funktioniert,
dass man halt hier immer diese Nicht-Herminale ersetzen muss,
auf Basis von weiteren Regeln.
Und dass ihr euch dann überlegen könnt,
welche Kombinationsmöglichkeiten gibt es denn jetzt hier?
Wie viele verschiedene Ausdrücke definiert diese Grammatik
Sicher. Ah, wir sind schon wieder ganz gut vorangekommen,
160, 170, also bei 200 spätestens mache ich Schluss.
Es wird jetzt ein bisschen zäh. Gut, ich halte es
mal an. Sehr schön, wir sind auch bei 200.
So, wir gucken mal auf die Verteilung. Ja,
es ist wieder sehr, sehr verteilt, wie viele Möglichkeiten es gibt.
Das ist immer ein Hinweis, dass sich das entweder
nicht gut erklärt habe oder ähnlich gut aufgepasst hat.
Ich würde sagen, heute habe ich schlecht erklärt,
weil es ein bisschen schnell war
Die richtige Antwort ist, es sind neun. Weil ich
kann Bezeichner, entweder durch A, B oder C ersetzen.
Es gibt also drei Möglichkeiten. Und ich kann hier bezeichnen
auch nochmal durch A, B oder C ersetzen.
Das sind dann alle Kombinationsmöglichkeiten, sind genau neun.
Dreimal drei. Okay. Ich habe noch so eine...
Einen habe ich noch, dann machen wir Schluss.
Wie viele verschiedene Zuweisungen definiert diese Grammatik
Also diese eckigen Klammern hier bedeuten optional, kann auftauchen,
muss nicht auftauchen. Und das ist wieder so eine Alternative.
Also entweder Bezeichner kann A oder B sein.
Da ist jetzt die Frage, sind es drei Möglichkeiten?
Sind es acht, sind es neun oder sind es
beliebig viele
Okay, meine Zeit ist abgelaufen, deswegen verende ich das
jetzt einfach mal, entscheidet euch für irgendwas, ganz spontan.
Okay, okay, 200 Stimmen, noch nicht ganz,
ich halte es mal an.
Wir gucken mal auf die Verteilung. Ah, okay,
acht sagen immerhin 53 Prozent und das ist auch richtig
Ja, weil ich kann Bezeichner durch A und B setzen und
hier auch bezeichnen durch A und B und bei allen Ableitungen,
bei diesen vier Ableitungsmöglichkeiten gibt es immer die Möglichkeit,
dass ein Plus dazwischen steht oder nicht,
weil das ja optional ist.
Also insgesamt acht Möglichkeiten und damit sind wir für heute
fertig.
Vielen Dank