Getter
Standard-Getter
So wie der Compiler automatisch einen Standard-Setter hinzufügt, fügt er auch einen sogenannten Getter hinzu, der den lesenden Zugriff auf ein Attribut steuert. Auch den Standard-Getter siehst du nicht in dem von dir geschriebenen Code, aber er wird beim Übersetzen in das ausführbare Programm automatisch hinzugefügt.
Auch ein Getter erinnert an eine Methode, hat aber in Kotlin eine spezielle Syntax, die ihn von einer normalen Methode unterscheidet. Den Standard-Getter könnte man in Kotlin so schreiben, wenn man ihn explizit angeben möchte:
class Timer {
var min: Int = 0
get() {
return field
}
// Rest der Klasse ...
}
fun main() {
val timer = Timer()
timer.min = 5 // Hier wird automatisch der Setter aufgerufen
println(timer.min) // Hier wird automatisch der Getter aufgerufen
}
Aufgabe 1
(a) Beschreibe den Aufbau eines Getters in Kotlin.
Experimentiere dazu mit dem obigen Code.
Versuche z.B. field umzubenennen
oder ändere die Formatierung wie z.B. die Einrückung oder Zeilenumbrüche.
(b) Ändere den Getter so ab, dass das Attribut min
unabhängig von dem Wert, der ihm zugewiesen wird, beim Lesen
immer den Wert 20 zurückgibt.
(Das ist natürlich nicht sinnvoll, aber es soll zeigen, wie ein
Getter funktioniert.)
Lesenden Zugriff auf Attribute steuern
Normalerweise gibt ein Getter einfach den Wert eines Attributs zurück, aber theoretisch könnte er auch eine Berechnung durchführen, bevor er einen Wert zurückgibt:
class FakeTimer {
var min: Int = 0
get() {
return field + 1
}
}
fun main() {
val timer = FakeTimer()
println(timer.min)
timer.min = 5
println(timer.min)
timer.min = 8
println(timer.min)
}
Aufgabe 2
Beschreibe den oben dargestellten Getter und formulieren eine Vermutung, welche Ausgabe das Hauptprogramm erzeugt. Überprüfe deine Vermutung, indem du das Hauptprogramm ausführst.
Berechnete Eigenschaften
In der Praxis nutzt man selbst definierte Getter normalerweise natürlich nicht, um die
Werte von Attributen zu verfälschen.
Man nutzt sie vielmehr, um Eigenschaften zu berechnen, die von anderen Attributen
abhängen.
Man nennt solche Eigenschaften auch computed properties.
Die berechnete Eigenschaft selbst speichert keinen Wert,
sondern berechnet ihren Wert jedes Mal neu, wenn sie gelesen wird.
Im Fall unseres Timers könnte man z.B. eine computed property zeitspanne
definieren, welche die Zeitspanne zwischen der minimalen und maximalen Zeit
berechnet und zurückgibt.
Für die berechnete Eigenschaft zeitspanne sieht das konkret so aus:
class Timer {
var min: Int = 0
var max: Int = 0
val zeitspanne: Int
get() {
return max - min
}
}
fun main() {
val timer = Timer()
// Hier solltest du den Timer noch testen
}
Aufgabe 3
(a) Betrachte die Implementierung der berechneten Eigenschaft zeitspanne
und beschreibe die Unterschiede zu einem normalen Attribut.
(b) Schreibe ein Hauptprogramm, das einen Timer erzeugt, die minimalen und maximalen Zeiten setzt und die Zeitspanne ausgibt. Nutze dazu das BlueJ-Projekt oder die Online-Version oben.
Methode oder Eigenschaft?
Berechnete Eigenschaften könnte man eigentlich genauso gut mit Methoden implementieren, hier also z.B. mit einer Methode, die die Zeitspanne berechnet und zurückgibt. In einigen Sprachen gibt es keine berechneten Eigenschaften, sondern nur Methoden, um Werte zu berechnen, die von anderen Attributen abhängen. In Kotlin können wir entweder Methoden oder berechnete Eigenschaften verwenden. Es empfiehlt sich aber, berechnete Eigenschaften zu verwenden, da man dadurch besser zwischen Eigenschaften, also den Werten eines Objekts, und Methoden, also den Fähigkeiten eines Objekts, unterscheiden kann. Dass eine Eigenschaft berechnet wird und nicht als normales Attribut gespeichert wird, kann man auch im Klassendiagramm darstellen:
Wir verwenden im Folgenden eher berechnete Eigenschaften (oder auf Englisch: computed properties) als Methoden. Es ist aber auch nicht verboten oder falsch, Methoden statt computed properties zu verwenden.
Aufgabe 4
(a) Zeichne ein Klassendiagramm für die Klasse Timer,
in dem die Zeitspanne in einer Methode berechnet wird.
(b) Implementiere die Methode und teste sie in einem Hauptprogramm.
(c) Vergleiche die Methode mit der berechneten Eigenschaft zeitspanne
in Bezug auf die Definition und die Verwendung.