Scala Funktionale (Zustandslose) Objekte Agenda Was sind Funktionale Objekte? veränderliche Objekte vs. unveränderliche Objekte Klassen Parameter Konstruktoren Private Member Methoden und Operatoren Overriding (Überschreiben) Was sind Funktionale Objekte? Objekte die unveränderlich sind z.B. String veränderliche Objekte vs. unveränderliche Objekte veränderliche Objekte vs. unveränderliche Objekte Veränderliche Objekte Unveränderliche Objekte Vor der Übergabe muss man eine Kopie herstellen Leichter verständlich Bsp: Objekt → Hashmap → wird dann verändert = > nicht wieder findbar 2 Threads können das Objekt nicht korrumpieren Können leicht übergeben werden Sichere Hashtable Schlüssel (­) Kopie statt Update Beispiele Implementierung einer Klasse zur Darstellung von Komplexen Zahlen. Klassen Parameter Klassen Parameter Class Klassenname(n: Int, d: Int) n,d werden Klassenparameter genannt Klassenparameter können nur in der Klasse genutzt werden! Compiler generiert einen Primär Konstruktor Trick: wird vor die Parameter val geschrieben, erstellt der Compiler automatisch Klassenvariablen Konstruktoren Konstruktoren Primärkonstruktor: Alles was nach dem Kopf steht und nicht in einer Methode steht wird ausgeführt → bildet also den Primärkonstruktor. Um Variablen eines übergebenen Objekts lesen zu können müssen sie vals sein → bei unveränderlichen Objekten muss dies bei der Initialisierung geschehen. Der Primärkonstruktor ist immer der Einstiegspunkt in eine Klasse. Konstruktoren Auxiliary Konstruktoren: Definition: Hilfskonstruktor, Sekundärkonstruktor. this wird als Name verwendet und nicht der Klassenname. z.B def this(n: Int) … Als erstes muss immer ein anderer Konstruktor aufgerufen werden! (textlich vor dem Aufrufenden) Letztendlich Aufruf des Primärkonstruktors. Nur der Primärkonstruktor kann super­Klassen K­ Konstruktoren Einschub zum hinzufügen von Klassenvariablen Um Variablen eines übergebenen Objekts lesen zu können müssen sie vals sein z.B. class Rational(n: Int, d: Int) { Val numer = n Val denom = d Leichter verständlich Private Member Private Member Das Schlüsselwort ist private. Kann bei Variablen und Methoden angewendet werden. Hat die selbe Wirkung wie bei Java. Der Defaultwert in Scala ist public. Methoden und Operatoren Methoden und Operatoren Definition mit Schlüsselwort „def“. Dann einer oder mehrere erlaubte Bezeichner, Gefolgt von Parametern in Klammern Dahinter wird dann „: “ + Typ des Rückgabewerts angegeben. Wenn die Methode mehr als eine Zeile Lang ist schreibt man noch „= { Was geschen soll } z.B.: def add(other: Rational): Unit = { … } Methoden und Operatoren Bezeichner in Scala : Alphanumerischen Operatoren Gemischten Buchstäblichen (literal) Methoden und Operatoren Alphanumerische Bezeichner: Unterstrich oder Buchstabe gefolgt von weiteren Buchstaben, Nummern oder Unterstrichen „$“ zählt als Buchstabe ist aber reserviert für den Scala Compiler Bezeichner in Programmen sollten es nicht enthalten, werden aber kompiliert (kann zu Konflikten führen) Methoden und Operatoren Namenskonventionen: Camel case (klein): Variabelnamen, Parameter von Methoden, lokale Variablen und Funktionen. Camel case (groß): Traits und Klassennamen. Zum Unterstrich: z.B. Val name_: Int = 1 Der Compiler liest „name_:“ und nicht „name_“: Methoden und Operatoren Scala vs. Java val != finals Parameter sind vals → Sie können bei jedem Aufruf verschieden sein. Java: finals → alles groß, Unterstrich als Trennzeichen Scala: der erste Buchstabe sollte groß sein X_OFFSET → Xoffset Methoden und Operatoren Operator Bezeichner: Operator Zeichen sind druckbare ASCII Zeichen wie z.B. +,:,?,~,# Noch genauer gehören die Operator Zeichen zur UniCode Menge aller mathematischen Symbole (Sm) oder zu den anderen („other“) Symbolen (So) Intern werden Symbole in legale Java Bezeichner umgewandelt (mit Einbettung des „$“ Zeichens) z.B. :­> → $colon$minus$greater Methoden und Operatoren Gemischte Bezeichner: Alphanumerischer Bezeichner + Unterstrich + ein Operator Bezeichner z.B. unary_+ Methoden und Operatoren Buchstäblichen Bezeichner (literal) Willkürliche Strings eingeschlossen von Hochkommas Idee: man kann irgendeinen Bezeichner nehmen der von der Laufzeit akzeptiert wird. Das Resultat ist immer ein Scala Bezeichner Es Funktioniert auch bei reservierten Wörtern z.B. Thread.`yield`() (yield ist reserviert) Overriding Overriding (Überschreiben) Überschreiben von geerbten Methoden. Schlüsselwort ist override Override + Methodendefinition Ist optional beim Überschreiben einer Abstrakte n Methode z.B. override def toString = numer + „/“ + denom Wieso? Leichtere Fehlersuche. Overloading Overloading Analog wie bei Java. Bei einem Aufruf entscheidet der Compiler welche Methode zu wählen ist, indem er das passende Argument heraussucht. Bei den Operatoren wird durch den rechten Operanden entschieden. Wenn es keinen einzigartigen, besten zutreffenden Fall gibt, bekommt man vom Compiler eine „ambiguous reference error“ Implizite Konvertierung Implizite Konvertierung Sagt dem Compiler was er tun soll, wenn ein Objekt keine Methode hat das übergebene Objekt zu handhaben. z.B. x = Int; y = Rational X + y → Ints haben keine Methode um Rationals zu addieren Lösung: implicit def intToRational(x: Int) = new Rational(x) Implizite Konvertierung One­at­a­time Rule: Nur eine Konvertierung, verschachteln nur bedingt möglich. Explicits­First Rule: Der Compiler verändert keinen funktionierenden Code. Non­Ambiguity Rule: Der Compiler weigert sich wenn er die Wahl hat für mehrere implizite Konvertierungen. Scope Rule: Die Konvertierung muss im Scope sein. Überprüfen von Vorbedingungen Überprüfen von Vorbedingungen Sicherstellen, dass die Daten korrekt sind Besonders Wichtig bei Unveränderlichen Objekten Scala bietet extra die require Methode. require(„boolean Ausdruck“) Falls der Ausdruck false ergibt wird eine IllegalArgumentException geworfen. Self Referenz Self Referenz Im Prinzip wie in Java Innerhalb einer Methode zeigt es auf das Objekt, das die Methode ausführt. Im Konstruktor auf das Objekt, das instantiiert wird. Meistens verwendet als Rückgabewert If Anweisung Liefert einen Wert zurück Val example = if(boolean) result1 else result2 Ermöglicht das verwenden von val anstatt var. Code wird leichter verständlich. Quellen Martin Odersky: Programming in scala artima 2008 Wampler, Payne: Programming Scala O´Ŕeilly 2009 Schluss Vielen Dank für eure Aufmerksamkeit :­)