Klassen und Properties
Groovy erzeugt Getter und Setter automatisch. Eigenschaften ohne Sichtbarkeit sind public mit Zugriffsmethoden:
class Person {
String name
int alter
private int geheim = 42
String toString() { "$name ($alter)" }
boolean istVolljaehrig() { alter >= 18 }
static Person kind(String name) { new Person(name: name, alter: 5) }
}
def p = new Person(name: "Mia", alter: 17)
println p
p.alter = 18 // ruft setAlter(18) auf
println p.alter
println p.istVolljaehrig()
println Person.kind("Ben")
println p.getName()
println p.properties.keySet().sort()
println p.metaClass.respondsTo(p, "istVolljaehrig").size() > 0
p.name += " Muster"
println p.nameAusgabe
Mia (17) 18 true Ben (5) Mia [alter, class, geheim, name, tVolljaehrig] true Mia Muster
Vererbung und Interfaces
interface Tier { String laut() }
abstract class Lebewesen implements Tier {
String name
String vorstellen() { "$name sagt ${laut()}" }
}
class Hund extends Lebewesen {
String laut() { "Wau" }
}
class Katze extends Lebewesen {
String laut() { "Miau" }
}
def tiere = [new Hund(name: "Rex"), new Katze(name: "Mimi")]
tiere.each { println it.vorstellen() }
println tiere*.class*.simpleName
println tiere[0] instanceof Tier
println tiere.collect { it.laut() }Ausgabe
Rex sagt Wau Mimi sagt Miau [Hund, Katze] true [Wau, Miau]
Traits
Traits sind wiederverwendbare Verhaltensbausteine, die man in mehrere Klassen mischen kann:
trait Begruesser {
String name
String gruss() { "Hallo, ich bin $name" }
}
trait Zaehler {
int zaehler = 0
void erhoehe() { zaehler = zaehler + 1 }
}
class Bot implements Begruesser, Zaehler {}
def b = new Bot(name: "R2")
println b.gruss()
b.erhoehe(); b.erhoehe()
println b.zaehlerAusgabe
Hallo, ich bin R2 2
AST-Transformationen
Annotationen erzeugen Standardcode zur Übersetzungszeit:
import groovy.transform.*
@ToString(includeNames = true)
@EqualsAndHashCode
@TupleConstructor
class Punkt {
int x
int y
}
@Canonical
class Konto {
String inhaber
double stand = 0
}
@Immutable
class Geld {
String waehrung
BigDecimal betrag
}
@Memoized
long fib(int n) { n < 2 ? n : fib(n - 1) + fib(n - 2) }
def a = new Punkt(1, 2)
def b = new Punkt(x: 1, y: 2)
println a
println a == b
println new Konto("Mia", 50)
def g = new Geld("EUR", 9.99)
println g
try { g.betrag = 1 } catch (ReadOnlyPropertyException e) { println "unveränderlich" }
println fib(60)Ausgabe
Punkt(x:1, y:2) true Konto(Mia, 50.0) Geld(EUR, 9.99) unveränderlich 1548008755920
Merke
- Klassen haben automatische Getter/Setter; Named-Parameter-Konstruktoren sind eingebaut
interface,abstract classundtraitstrukturieren Code- Traits mischen Verhalten und Zustand in Klassen
@ToString,@EqualsAndHashCode,@Immutable,@Memoizedsparen Boilerplate
Aufgabe
Modelliere ein Konto mit einzahlen und abheben und teste es mit @ToString.