1. OOP in Scala
Seminar Softwareentwicklung mit Scala
Wintersemester 2010/11
Martin Pfeiffer
Friedrich Schiller Universit¨at Jena
Prof. Dr. Wolfram Amme
Christoph Henniger
Christian Schachtzabel
22. November 2010
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 1 / 30
2. ¨Ubersicht
1 Klassen & Objekte
2 Klassenmember
3 Vererbung
4 Weitere Konzepte
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 2 / 30
3. Klassen & Objekte
Klassen
Klassendefinition
Definition mit Schl¨usselwort class
Klassenname und Dateiname m¨ussen nicht ¨ubereinstimmen
Mehrere
”
public“ Klassen pro Datei zul¨assig
M¨ussen nicht im Ordner ihres Paketes definiert werden
Verwendung
Mit new werden neue Instanzen erzeugt
Kein delete, vernichten ¨ubernimmt GC
Referenzsemantik wie in Java
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 3 / 30
4. Klassen & Objekte
Klassen
Klassendefinition
Definition mit Schl¨usselwort class
Klassenname und Dateiname m¨ussen nicht ¨ubereinstimmen
Mehrere
”
public“ Klassen pro Datei zul¨assig
M¨ussen nicht im Ordner ihres Paketes definiert werden
Verwendung
Mit new werden neue Instanzen erzeugt
Kein delete, vernichten ¨ubernimmt GC
Referenzsemantik wie in Java
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 3 / 30
5. Klassen & Objekte
Klassen
class Person
{
var name : String = "";
}
object ClassesExample {
def main(args: Array[String]) : Unit = {
val peter = new Person()
peter.name = "Peter"
val horst = new Person()
horst.name = "Horst"
println("Persons name is: "+peter.name)
println("Persons name is: "+horst.name)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 4 / 30
6. Klassen & Objekte
Objekte
Objektdefinition
Objekte haben nur eine
”
Instanz“
Implementierung des Singleton Design Pattern
Definition mit Schl¨usselwort object
Verwendung
Referenzen kann Name des object zugewiesen werden
Verh¨alt sich wie Instanz einer Klasse
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 5 / 30
7. Klassen & Objekte
Objekte
Objektdefinition
Objekte haben nur eine
”
Instanz“
Implementierung des Singleton Design Pattern
Definition mit Schl¨usselwort object
Verwendung
Referenzen kann Name des object zugewiesen werden
Verh¨alt sich wie Instanz einer Klasse
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 5 / 30
8. Klassen & Objekte
Objekte - Beispiel
object Person{
var name : String = "";
}
// Die Referenzen peter und horst verweisen auf das selbe object
object ObjectExample {
def main(args: Array[String]) : Unit = {
val peter = Person
peter.name = "Peter"
val horst = Person
horst.name = "Horst"
println("Person name is: "+peter.name)
println("Person name is: "+horst.name)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 6 / 30
10. Klassenmember
Membervariablen
Memberdefinition
var - Sind Variablen
val - Value - Sind Werte
Achtung - Alles in Scala ist per Default
”
public“
Type eines initialisierten Member optional
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 8 / 30
11. Klassenmember
Membervariablen - Beispiel
class Person{
val name : String = "Default name"
//Type ergibt sich aus Wertzuweisung
var alter = 42
}
object MemberExample {
def main(args: Array[String]) : Unit = {
val peter = new Person()
//peter.name = "peter" -> Error - value nicht aenderbar
peter.alter = 43
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 9 / 30
12. Klassenmember
Methoden
def methodenName (param1 : ParamType) : ReturnType =
{
//Methodenkoerper
}
Eigenschaften
Werden durch das Schl¨usselwort def definiert
Name der Methode erlaubt Sonderzeichen!
Parameterliste optional
R¨uckgabetype optional wenn eideutig
Notwendig bei return und Rekursion
Bei einzeiligen Methodenk¨orper {} optional
Wert der letzten Anweisung wird automatisch zur¨uckgegeben
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 10 / 30
13. Klassenmember
Methoden
def methodenName (param1 : ParamType) : ReturnType =
{
//Methodenkoerper
}
Eigenschaften
Werden durch das Schl¨usselwort def definiert
Name der Methode erlaubt Sonderzeichen!
Parameterliste optional
R¨uckgabetype optional wenn eideutig
Notwendig bei return und Rekursion
Bei einzeiligen Methodenk¨orper {} optional
Wert der letzten Anweisung wird automatisch zur¨uckgegeben
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 10 / 30
14. Klassenmember
Methoden - Beispiel
class SInt(i : Int){
val value : Int = i
def printValue() : Unit = { println(value) }
def +(other : SInt) : SInt = new SInt(value+other.value)
def ! = {
var k = 1
for(i <- 1 to value)
k *= i
new SInt(k)
}}
object MethodeExample{
def main(args: Array[String]): Unit= {
val i1 = new SInt(5)
val i2 = new SInt(2)
(i2 + i1).printValue
(i1!).printValue
}}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 11 / 30
15. Klassenmember
Hauptkonstruktoren
class Example(param1 : Paramtype)
{
val member : Paramtype = param1
}
Eigenschaften
Jede Klasse hat genau 1 Hauptkonstruktor
(Leere) Parameterliste direkt nach Klassennamen
K¨orper der Klasse ist Kontruktork¨orper
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 12 / 30
16. Klassenmember
Hauptkonstruktoren
class Example(param1 : Paramtype)
{
val member : Paramtype = param1
}
Eigenschaften
Jede Klasse hat genau 1 Hauptkonstruktor
(Leere) Parameterliste direkt nach Klassennamen
K¨orper der Klasse ist Kontruktork¨orper
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 12 / 30
17. Klassenmember
Hauptkonstruktoren - Beispiel
class Person(n : String, i : Int)
{
private val name = n
private var alter = i
}
object ConstructorExample {
def main(args: Array[String]) = {
val peter = new Person("peter", 42)
val horst = new Person("horst", 37)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 13 / 30
18. Klassenmember
Hauptkonstruktoren - Besonderheiten
Codereduzierung
Parameter optional mit var bzw. val
F¨ur var Parameter wird private var + Getter + Setter angelegt
F¨ur val Parameter wird private val + Getter angelegt
class Person(val name : String, var alter : Int)
object GetterSetterExample{
def main(args: Array[String]) = {
val peter = new Person("peter", 42)
println(peter.name)
//peter.name = "horst" -> Error
peter.alter = 43
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 14 / 30
19. Klassenmember
Hauptkonstruktoren - Besonderheiten
Codereduzierung
Parameter optional mit var bzw. val
F¨ur var Parameter wird private var + Getter + Setter angelegt
F¨ur val Parameter wird private val + Getter angelegt
class Person(val name : String, var alter : Int)
object GetterSetterExample{
def main(args: Array[String]) = {
val peter = new Person("peter", 42)
println(peter.name)
//peter.name = "horst" -> Error
peter.alter = 43
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 14 / 30
20. Klassenmember
Hilfskonstuktoren
Eigenschaften
Hilfskonstruktoren sind Methoden mit dem Namen this
() auch bei parameterlosen Konstruktor notwendig
M¨ussen sich in ihrer Signatur unterscheiden
M¨ussen als erste Anweisung einer anderen Konstuktor aufrufen
Dieser muss oberhalb des aktuellen definiert sein
Kein R¨uckgabewert - auch nicht Unit
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 15 / 30
21. Klassenmember
Hilfskonstruktoren - Beispiel
class Person(n : String, i : Int)
{
private val name = n
private var alter = i
def this(n : String) = this(n, 42)
def this() = this("unknown")
}
object ConstructorExample {
def main(args: Array[String]) = {
val peter = new Person("peter")
val horst = new Person("horst", 37)
val unknown = new Person
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 16 / 30
22. Klassenmember
Getter & Setter in Scala
//Analog zu class Person(var name : String)
class Person(n : String)
{
private var _name : String = n
def name = _name
def name_= (n : String) = _name = n
}
Uniform Access Principle
Memberzugriff von Methodenaufruf nicht zu unterscheiden
Implementierung der Klasse kann ge¨andert werden
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 17 / 30
23. Klassenmember
Getter & Setter in Scala
//Analog zu class Person(var name : String)
class Person(n : String)
{
private var _name : String = n
def name = _name
def name_= (n : String) = _name = n
}
Uniform Access Principle
Memberzugriff von Methodenaufruf nicht zu unterscheiden
Implementierung der Klasse kann ge¨andert werden
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 17 / 30
24. Klassenmember
POJO’s in Scala
Problem mit Java Kompatibilit¨at
Java Beans erfodern getX(), setX() & isX() Methoden
Zahlreiche Frameworks setzen auf diesen Eigenschaften auf
Annotation @scala.reflect.BeanProperty bringt Bean Eigenschaften
class Person(@scala.reflect.BeanProperty val name : String,
@scala.reflect.BeanProperty var alter : Int)
object POJOExample {
def main(args: Array[String]) = {
val peter = new Person("peter", 42)
println(peter.getName())
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 18 / 30
25. Klassenmember
POJO’s in Scala
Problem mit Java Kompatibilit¨at
Java Beans erfodern getX(), setX() & isX() Methoden
Zahlreiche Frameworks setzen auf diesen Eigenschaften auf
Annotation @scala.reflect.BeanProperty bringt Bean Eigenschaften
class Person(@scala.reflect.BeanProperty val name : String,
@scala.reflect.BeanProperty var alter : Int)
object POJOExample {
def main(args: Array[String]) = {
val peter = new Person("peter", 42)
println(peter.getName())
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 18 / 30
27. Vererbung
Vererbung
Eigenschaften
Scala kennt wie Java keine Mehrfachvererbung!
Definition
Vererbung durch Schl¨usselwort extends bei Klassendefinition
Es muss dabei ein Konstruktor der super Klasse aufgerufen werden
Kein Superkonstruktoraufruf f¨ur Hilfskonstruktoren m¨oglich
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 20 / 30
28. Vererbung
Vererbung
Eigenschaften
Scala kennt wie Java keine Mehrfachvererbung!
Definition
Vererbung durch Schl¨usselwort extends bei Klassendefinition
Es muss dabei ein Konstruktor der super Klasse aufgerufen werden
Kein Superkonstruktoraufruf f¨ur Hilfskonstruktoren m¨oglich
class Person (var name : String, val alter : Int){
def this(name : String) = this(name, 42)
}
class Dozent(name : String, var fach : String)
extends Person(name)
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 20 / 30
29. Vererbung
Vererbung
Eigenschaften
Scala kennt wie Java keine Mehrfachvererbung!
Definition
Vererbung durch Schl¨usselwort extends bei Klassendefinition
Es muss dabei ein Konstruktor der super Klasse aufgerufen werden
Kein Superkonstruktoraufruf f¨ur Hilfskonstruktoren m¨oglich
class Person (var name : String, val alter : Int){
def this(name : String) = this(name, 42)
}
class Dozent(name : String, var fach : String)
extends Person(name)
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 20 / 30
30. Vererbung
Abstrakte Klassen
Definition
Abstrakte Klassen durch das Schl¨usselwort abstract
Notwendig wenn Klasse abst. Methoden oder Variablen enth¨alt
Instanzen k¨onnen nur von nicht abstrakten Klassen erzeugt werden
Abstrakte Variablen & Methoden
Abstrakte Methoden sind Methoden ohne K¨orper
z. B.: def print() : Unit
Abstrakte Variablen sind var & val ohne Zuweisung
z. B.: val con : Connection
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 21 / 30
31. Vererbung
Abstrakte Klassen
Definition
Abstrakte Klassen durch das Schl¨usselwort abstract
Notwendig wenn Klasse abst. Methoden oder Variablen enth¨alt
Instanzen k¨onnen nur von nicht abstrakten Klassen erzeugt werden
Abstrakte Variablen & Methoden
Abstrakte Methoden sind Methoden ohne K¨orper
z. B.: def print() : Unit
Abstrakte Variablen sind var & val ohne Zuweisung
z. B.: val con : Connection
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 21 / 30
32. Vererbung
Abstrakte Klassen - Beispiel
abstract class Connection
class USBConnection extends Connection{
def print(s : String) : Unit = {/*..*/}
}
abstract class Printer{
val con : Connection
def print(s : String) : Unit
}
class USBPrinter extends Printer{
val con = new USBConnection
def print(s : String) : Unit = con.print(s)
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 22 / 30
33. Vererbung
¨Uberschreiben von Membern
Definition
Scala erlaubt das ¨Uberschreiben von nicht abstrakten Membern
Dazu dient das Schl¨usselwort override
So deklarierte Methoden & Variablen m¨ussen etwas ¨uberschreiben
Test durch Compiler - Java hat nur @overrride Annotation
class Person(val name : String, var alter : Int){
override def toString() = {
"Person: - name: "+name+" alter: "+alter
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 23 / 30
34. Vererbung
¨Uberschreiben von Membern
Definition
Scala erlaubt das ¨Uberschreiben von nicht abstrakten Membern
Dazu dient das Schl¨usselwort override
So deklarierte Methoden & Variablen m¨ussen etwas ¨uberschreiben
Test durch Compiler - Java hat nur @overrride Annotation
class Person(val name : String, var alter : Int){
override def toString() = {
"Person: - name: "+name+" alter: "+alter
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 23 / 30
36. Weitere Konzepte
Companion Objects
Problem
Scala kennt im Gegensatz zu Java kein
”
static“
Es gibt nur object um Einzigartigkeit zu erzeugen ¨uberschreiben
L¨osung
Eine Klasse & ein Object mit demselben Namen
M¨ussen in derselben Datei und im selben Paket deklariert werden
Bilden zusammen eine Companion Class bzw. Companion Object
Klasse kann auf private Object-Member zugreifen
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 25 / 30
37. Weitere Konzepte
Companion Objects
Problem
Scala kennt im Gegensatz zu Java kein
”
static“
Es gibt nur object um Einzigartigkeit zu erzeugen ¨uberschreiben
L¨osung
Eine Klasse & ein Object mit demselben Namen
M¨ussen in derselben Datei und im selben Paket deklariert werden
Bilden zusammen eine Companion Class bzw. Companion Object
Klasse kann auf private Object-Member zugreifen
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 25 / 30
38. Weitere Konzepte
Companion Objects
class Person(val name : String, var alter : Int){
def printObjectCount = println(Person.counter)
}
object Person{
private var counter = 0
def getInstance(name : String, alter : Int) = {
counter += 1
new Person(name, alter)
}
}
object CompanionObjectExample {
def main(args : Array[String]) = {
val peter = Person.getInstance("peter", 42)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 26 / 30
39. Weitere Konzepte
Companion Objects - Apply Methode
Vorraussetzung
Im Companion Object gibt es eine apply Methode
Diese kann ¨uber den Klassennamen benutzt werden
Oft als Factory-Methode benutzt
class Person(val name : String, var alter : Int)
object Person{
def apply(name : String, alter : Int)
= new Person(name, alter)
}
object ApplyExample{
def main(args : Array[String]) = {
val peter = Person("peter",42)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 27 / 30
40. Weitere Konzepte
Companion Objects - Apply Methode
Vorraussetzung
Im Companion Object gibt es eine apply Methode
Diese kann ¨uber den Klassennamen benutzt werden
Oft als Factory-Methode benutzt
class Person(val name : String, var alter : Int)
object Person{
def apply(name : String, alter : Int)
= new Person(name, alter)
}
object ApplyExample{
def main(args : Array[String]) = {
val peter = Person("peter",42)
}
}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 27 / 30
41. Weitere Konzepte
Case Classes
Vorteile
Kann f¨ur das Pattern Matching benutzt werden
Alle Konstruktorparameter automatisch als val
equals und hashCode werden automatisch erzeugt
toString mit Klassenname sowie allen Parametern
Automatische apply Methode mit allen Parametern
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 28 / 30
42. Weitere Konzepte
Case Classes - Beispiel
abstract class Person(name : String)
case class Dozent(name: String, fachbereich : String) extends
Person(name)
case class Student(name: String, semester : Int) extends
Person(name)
object ApplyExample{
def main(args : Array[String]) = {
action(Student("peter", 7))
action(Dozent("horst", "Biologie"))
}
def action(person : Person) = person match{
case Student(name: String, semester : Int) =>
println(name+" ist im Semester "+semester)
case Dozent(name: String, fachbereich : String) =>
println(name+" gehoert zum Fachbereich "+fachbereich)
}}
m.pfeiffer@uni-jena.de OOP in Scala 22. November 2010 29 / 30