EMZETT.
Login

Kurz: object Zaehler: private var n = 0 def naechster(): Int = n += 1 n

Teil des Kurses Scala

Kapitel 4 von 8 im Kurs Scala (Abschnitt „Objektorientiert und funktional“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

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

  • class mit Primärkonstruktor in der Klassenkopfzeile; val/var macht Parameter zu Feldern
  • object = Singleton, Companion Object für statische Teile
  • case class liefert Gleichheit, copy, toString und Pattern Matching
  • trait = Schnittstelle + Verhalten, mehrere Traits mischbar

Übungsaufgabe

Modelliere Fahrzeug als Trait mit zwei Case-Class-Implementierungen und sortiere eine Liste.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Collections und Pattern Matching

Weiter: Enums, ADTs und Fehlerbehandlung

Alle Kapitel: Scala im Überblick