Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

Scala Grundkurs

Allgemeine Klassen

Testen Sie unsere 2016 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Neben Funktionen sind Klassen in Scala sehr wichtig. Da Scala im Vergleich zu herkömmlichen Programmiersprachen diverse Besonderheiten beim Umgang mit Klassen aufweist, geht dieses Video besonders intensiv auf dieses Thema ein.

Transkript

Aufgrund der Objektorientierung sind in Scala auch Klassen wichtig neben den Funktionen. Nichtsdestotrotz gibt es diverse Unterschiede zu herkömmlichen Programmiersprachen wie Java. Und genau auf diese Besonderheiten möchte ich nun eingehen. Ich befinde mich nun also in meiner Applikation. Hier existiert bereits eine Klasse mit der Bezeichnung "Application" in Form eines "object". Diese Klasse befindet sich innerhalb einer ".scala"-Datei. Anders als beispielsweise in Java habe ich nun die Möglichkeit, auch innerhalb einer Scala-Datei mehr als eine Klasse zu definieren. Beispielsweise die Klasse "Customer". Selbstverständlich ist das nicht immer guter Stil. Und üblicherweise sollten Klassen sich außerhalb einer einzelnen Scala-Datei befinden und meistens eine eigene Datei haben. Dennoch werde ich nun zu Demonstrationszwecken mit genau dieser Struktur weiterarbeiten. Was weiterhin auffällt ist, dass die Klasse "Customer" nun keinen Rumpf hat. Das bedeutet keine Implementierung und trotzdem ist die Definition der Klasse bereits gültig. Das heißt, innerhalb meiner "main"-Methode könnte ich nun eine Instanz dieser Klasse erstellen mit dem "new"-Keyword. Selbstverständlich hat mein "Customer" auch einige Felder. Anders als über einen regulären Konstruktor kann ich innerhalb von Scala die Argumente auf Ebene der Klasse definieren. Das bedeutet, für einen Vornamen vom Typ String und einen Nachnamen vom Typ String definiere ich das innerhalb der Klammern, unmittelbar hinter dem Typ. Selbstverständlich benötigt nun das Erzeugen einer Instanz von "Customer" diese beiden Argumente, beispielsweise nun also "Christopher" , "Janietz". Der "Customer" beinhaltet also nun diese beiden Parameter. Allerdings kann ich diese von außen nicht abrufen. Das bedeutet, es handelt sich dabei lediglich um Argumente, die innerhalb der Klasse gelten. Um nun beispielsweise ein Feld zu erstellen, das auf der Klasse sichtbar ist, öffne ich nun einen Rumpf für diese Klasse und definiere beispielsweise ein Feld "fullName", das sich zusammensetzt aus dem Vornamen und dem Nachnamen. Genau dieses Feld kann ich nun auch von außen abrufen, mit beispielsweise dem "println"-Befehl und dem Aufruf des Feldes. Bei der Zuweisung des Feldes kann es sich auch um einen Methodenrumpf handeln Das bedeutet, wenn ich nun geschweifte Klammern einführe, kann ich beispielsweise auch zusätzlich noch einen "println"-Befehl ausführen, wie beispielsweise den Text "Vor der Berechnung". Sollte das Feld nun also ausgewertet werden, wird zusätzlich diese Ausgabe gemacht. Sollte ich wünschen, dass dieses Feld nur dann ausgewertet wird, wenn es tatsächlich jemand nutzt, füge ich lediglich "lazy" vor dieses Value hinzu. Damit wird das Feld also nicht mehr beim Erstellen der Klasse zugewiesen. Dies beweise ich nun, indem ich vorher einen Text "Test" ausgebe. Dieser ist also nun sichtbar, obwohl die Klasse bereits erzeugt wurde. Allerdings wird das Feld "fullName" erst später abgerufen. Zusätzlich könnte ich nun eine Klasse "Basket" für Warenkorb erstellen. Diese benötigt nun eben einen "Customer" und verwaltet eine Liste von Produkten. Diese deklariere ich durch eine Sichtbarkeit mit "private" innerhalb des Warenkorbs. Dabei handelt es sich um eine Variable, da sich der Inhalt des Warenkorbs ändern wird. Und diese Variable besteht nun aus einer leeren Liste. Selbstverständlich benötige ich nun noch eine Klasse für ein Produkt. Also beispielsweise die Klasse "Product", in dem es einen Produktnamen gibt, und einen Preis. Bis jetzt ist meine Liste noch nicht typisiert. Das bedeutet, dass sie jegliche Art von Inhalt nehmen kann. Wenn ich nun möchte, dass es sich dabei um eine Liste von Produkten handelt, kann ich dies über den Typenparameter tun, in dem Fall also hier definiert durch das "A". Ich füge also eckige Klammern hinzu und gebe den Typ "Product" an. Jetzt handelt es sich also nun um eine Liste vom Typ "Product", die bis jetzt leer ist. Als Nächstes könnte ich nun den Typ "Product" spezialisieren. Beispielsweise könnte ich ein Produkt haben, das lediglich online verfügbar ist. Deswegen nenne ich nun die Klasse "OnlineProduct" und deklariere "Product" nun als abstrakte Klasse, sodass keine Instanz davon erzeugt werden kann. Um hier Vererbung zu signalisieren, verwende ich das Keyword "extends", in dem Fall also nun "Product". An der Stelle bekomme ich nun den Hinweis darauf, dass"Product" Argumente hat, beispielsweise also nun den Namen und den Preis. Diese müsste ich nun übergeben. Das bedeutet, meine Klasse "OnlineProduct" nimmt in dem Fall also auch Argumente entgegen und gibt diese weiter an die Ursprungsklasse. Wenn ich nun noch ein Interface hinzufügen möchte zu meiner Klasse "OnlineProduct", würde ich nicht wie in Java das "implements"-Keyword verwenden, sondern lediglich eine Erweiterung von dem "extends"-Begriff. In dem Fall also "extends" und dann "with" und beispielsweise dem Interface "Serializable" für eine serialisierbare Klasse. Als Nächstes wäre es noch sinnvoll, eine Methode auf dem Warenkorb zu schaffen, die es möglich macht, ein Produkt hinzuzufügen. Ich nenne diese Methode also "addItem", die ein solches Produkt entgegennimmt. Bei meiner Liste handelt es sich hier um ein "immutable" Objekt. Das bedeutet, sofern ich die Liste erweitern möchte, muss ich eine neue Instanz der Liste erzeugen. Das heißt, ich weise dem Feld "items" eine neue Instanz der Liste zu, die dadurch entsteht, dass ich das "Product" zusätzlich an die bereits bestehende Liste hinzufüge. An der Stelle sollte man sich nicht von dieser doppelten Zuweisung verwirren lassen. Dabei handelt es sich lediglich um den Methodenrumpf. Dieser könnte auch beispielsweise in dieser Form ausgedrückt werden. Wichtig ist, dass in Scala Listen einen Operator definieren, der es erlaubt, ein Objekt, wie beispielsweise "Product", an die Liste anzuheften und dabei eine neue Liste zu erzeugen. Es gibt auch eine alternative Syntax, die noch etwas kürzer ist. Ich nehme also wieder ein "Product" entgegen und in diesem Fall weise ich "items" das "product" direkt zu. Wenn auch die Notation etwas anders aussieht, ist das Ergebnis das Gleiche. Allerdings erspart man sich hier, "items" noch einmal explizit zuzuweisen, denn das ergibt sich aus der Semantik der Notation, ähnlich wie bei einem mathematischen Ausdruck. Der große Vorteil einer solchen unveränderlichen Liste ist, dass ich nun, ohne Angst haben zu müssen, meine Liste auch anderen Nutzern beziehungsweise anderen Klassen bereitstellen kann. Das bedeutet, ich definiere eine Methode, die ich nun "getItems" nenne, und diese gibt lediglich die Liste zurück. Wenn also von außen jemand nun dieses "List"-Objekt ändern wollen würde, würde er automatisch eine neue Instanz der Liste erzeugen und nicht die Funktionalität meiner Klasse "Basket" beeinträchtigen. Ich erstelle nun also beispielsweise einen solchen "Basket" auf Basis meines bereits existenten Kunden. Zusätzlich erstelle ich noch ein Produkt vom Typ "OnlineProduct", beispielsweise einen Samsung-Fernseher, der 699,99 kostet, und nutze nun die beiden Möglichkeiten, ein Produkt in meinen Warenkorb hinzuzufügen. Zu guter Letzt kann ich mir nun den Inhalt des Warenkorbs ansehen, indem ich auf die Konsole "basket.getItems" ausgebe. Bedingt dadurch, dass die Methode "getItems" keine Argumente nimmt, kann man sie auch ohne Klammersetzung verwenden beim Aufruf. Das bedeutet auch, dass nun diese Methode beziehungsweise Funktion von außen wie ein Feld verwendet wird. Ich könnte also auch ein Value-Feld daraus machen und es würde dem Nutzer dieser Funktion nicht auffallen. Wenn ich die Applikation also nun starte, sehe ich meine Liste, in der das Produkt nun zweimal existiert. An dieser Stelle kann ich nun einige Verschönerungen vornehmen. Zum einen habe ich hier Methoden, die öffentlich sichtbar sind. Diese sollten üblicherweise, wie auch durch IntelliJ IDEA markiert, ihren Typ darstellen. Das bedeutet, wenn ich nun dank IntelliJ IDEA's Hilfe "Alt + Enter" drücke, kann ich eine Typ-Notation hinzufügen. Und IntelliJ IDEA erkennt also automatisch, dass diese Funktion eine Methode ist und daher keinen Rückgabewert hat. Ähnlich verhält es sich bei der "addItem2"-Funktion. Und die "getItems"-Funktion gibt eine Liste von Produkten zurück. Alle Variablen und Values als auch Methoden, die mit "private" oder "protected" deklariert sind, müssen nicht zwangsläufig einen Typ mit sich führen, da es sich dabei also um interne Implementierungen handelt. Allerdings bei öffentlichen Methoden sollte man aus diesen Gründen immer darauf achten, explizit anzugeben, welcher Typ aus der Funktion oder dem Value bereitgestellt wird. Zu guter Letzt kann ich noch innerhalb meiner abstrakten Klasse "Product" die Methode "toString" überschreiben. Hierfür existiert das Keyword "override" ähnlich wie in Java. Und ich könnte nun beispielsweise also einen String zurückgeben, der den Namen des Produkts enthält und dessen Preis. Gesehen haben Sie nun also Klassen innerhalb von Scala. Dabei waren einige Besonderheiten aufgetreten. Methoden beziehungsweise Funktionen werden hier durch Zuweisung deklariert. Des Weiteren werden Variablen und auch Value-Werte innerhalb der Instanz der Klasse erzeugt. Das bedeutet, anders als bei Java benötigt man keinen expliziten Konstruktor, um hier Zuweisungen zu machen, denn solche Value-Werte können auch eigene Logik implementieren, die bei der Definition des Value-Werts ausgeführt wird. Desweiteren habe ich Ihnen noch gezeigt, wie das Konstrukt "lazy val" innerhalb von Klassen angewendet wird. Die Vererbung findet in Scala mit einer etwas einheitlicheren Syntax statt. Damit verwendet man also lediglich das Keyword "extends". Und für die Implementierung bestimmter Interfaces verwendet man die Erweiterung "with".

Scala Grundkurs

Entdecken Sie die Möglichkeiten und Eigenschaften der modernen Programmiersprache Scala.

4 Std. 44 min (39 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Exklusiv für Abo-Kunden
Erscheinungsdatum:12.04.2017

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!