Geschichte der Frage:
Kotlin vereint die besten Seiten von Java und das funktionale Erbe der JVM. Normale Klassen werden als Standardstrukturen deklariert, abstrakte Klassen ermöglichen die Erstellung von unterdefinierten Vorlagen mit Standardimplementierung, und Schnittstellen unterstützen die mehrfache Vererbung von Verhalten ohne Zustand.
Problem:
Die richtige Wahl zwischen Klasse, abstrakter Klasse und Schnittstelle bestimmt die Architektur der Anwendung, die Granularität des Codes und dessen Erweiterbarkeit. Falsche Vererbung führt zu Schwierigkeiten bei Tests und zukünftigen Änderungen.
Lösung:
In Kotlin:
Beispielcode:
interface Drawable { fun draw() } abstract class Shape(var color: String) : Drawable { abstract fun calcArea(): Double override fun draw() = println("Shape drawn") } class Circle(color: String, val radius: Double) : Shape(color) { override fun calcArea() = Math.PI * radius * radius }
Wichtige Merkmale:
Können Schnittstellen Eigenschaften mit backing field enthalten?
Nein, sie können nur die Signatur einer Eigenschaft definieren, aber keine Daten speichern – Eigenschaften ohne backing field.
Kann man von mehreren Klassen erben?
Nein, Kotlin unterstützt nur einfache Klassenvererbung, aber mehrfache Implementierung von Schnittstellen.
Kann man einen Konstruktor in einer Schnittstelle deklarieren?
Nein, Schnittstellen unterstützen keine Konstruktoren, da sie keinen Zustand speichern – nur Verträge für Verhalten.
In der Anwendung wurden alle gemeinsamen Funktionen in eine abstrakte Klasse ausgelagert, selbst wenn es keine interne Logik oder Status gab, sondern nur einen gemeinsamen Vertrag erforderlich war.
Vorteile:
Nachteile:
Nur die erforderlichen Verträge wurden in Schnittstellen ausgelagert, abstrakte Klassen beschränkten sich auf gemeinsame Eigenschaften und Methoden, die eine Implementierung erforderten.
Vorteile:
Nachteile: