Klassen und Objekte
class Konto(val inhaber: String, private var stand: Double = 0.0):
def einzahlen(betrag: Double): Unit =
require(betrag > 0, "Betrag muss positiv sein")
stand += betrag
def kontostand: Double = stand
override def toString: String = f"Konto($inhaber, $stand%.2f)"
object Zaehler:
private var n = 0
def naechster(): Int =
n += 1
n
@main def main(): Unit =
val k = Konto("Mia", 10)
k.einzahlen(5.5)
println(k)
println(k.kontostand)
println(Zaehler.naechster())
println(Zaehler.naechster())
try k.einzahlen(-1)
catch case e: IllegalArgumentException => println(e.getMessage)Ausgabe
Konto(Mia, 15.50) 15.5 1 2 requirement failed: Betrag muss positiv sein
object ist ein Singleton. Ein object mit gleichem Namen wie eine Klasse heißt Companion Object und enthält statische Hilfen.
Case Classes
Case Classes liefern equals, hashCode, toString, copy und Pattern Matching automatisch:
case class Person(name: String, alter: Int):
def istVolljaehrig: Boolean = alter >= 18
object Person:
def kind(name: String): Person = Person(name, 5)
@main def main(): Unit =
val a = Person("Mia", 17)
val b = a.copy(alter = 18)
println(a)
println(b)
println(a == Person("Mia", 17))
println(b.istVolljaehrig)
println(Person.kind("Ben"))
val Person(n, al) = b
println(s"$n $al")
println(a.productElementNames.toList)
println(a.hashCode == Person("Mia", 17).hashCode)Ausgabe
Person(Mia,17) Person(Mia,18) true true Person(Ben,5) Mia 18 List(name, alter) true
Traits
Traits sind Schnittstellen mit optionalen Implementierungen und lassen sich mehrfach mischen:
trait Tier:
def name: String
def laut: String
def vorstellen: String = s"$name sagt $laut"
trait Laeufer:
def lauf(): String = "rennt"
class Hund(val name: String) extends Tier, Laeufer:
def laut = "Wau"
class Katze(val name: String) extends Tier:
def laut = "Miau"
override def vorstellen: String = super.vorstellen + "!"
@main def main(): Unit =
val tiere: List[Tier] = List(Hund("Rex"), Katze("Mimi"))
tiere.foreach(t => println(t.vorstellen))
println(Hund("Rex").lauf())
val anonym = new Tier:
val name = "Geist"
val laut = "Buh"
println(anonym.vorstellen)Ausgabe
Rex sagt Wau Mimi sagt Miau! rennt Geist sagt Buh
Abstrakte Klassen und Vererbung
abstract class Form:
def flaeche: Double
def beschreibung: String = f"${getClass.getSimpleName} mit Fläche $flaeche%.2f"
class Kreis(r: Double) extends Form:
def flaeche = math.Pi * r * r
class Rechteck(b: Double, h: Double) extends Form:
def flaeche = b * h
@main def main(): Unit =
List(Kreis(1), Rechteck(2, 3)).foreach(f => println(f.beschreibung))Ausgabe
Kreis mit Fläche 3.14 Rechteck mit Fläche 6.00
Merke
classmit Primärkonstruktor in der Klassenkopfzeile;val/varmacht Parameter zu Feldernobject= Singleton, Companion Object für statische Teilecase classliefert Gleichheit,copy,toStringund Pattern Matchingtrait= Schnittstelle + Verhalten, mehrere Traits mischbar
Aufgabe
Modelliere Fahrzeug als Trait mit zwei Case-Class-Implementierungen und sortiere eine Liste.