Wie sind Vererbung und Polymorphismus in Kotlin organisiert?
sobes.tech KI
Antwort von AI
In Kotlin wird Vererbung durch Klassen- und Schnittstellenmechanismen realisiert. Klassen können nur von einer anderen Klasse erben (einfache Vererbung), aber mehrere Schnittstellen implementieren.
Standardmäßig sind alle Klassen in Kotlin 'final', das heißt, sie können nicht vererbt werden. Um Vererbung zu erlauben, muss eine Klasse explizit mit dem Schlüsselwort open gekennzeichnet werden.
Klassenvererbung:
open class Shape { // Basisklasse, als open gekennzeichnet
open fun draw() { // Methode, die überschrieben werden kann
println("Zeichne eine Form")
}
}
class Circle : Shape() { // Erbt von Shape
override fun draw() { // Überschreibt die Methode
println("Zeichne einen Kreis")
}
}
Im Konstruktor der Kindklasse muss der Konstruktor der Basisklasse explizit oder implizit aufgerufen werden.
Schnittstellen:
Schnittstellen in Kotlin ähneln denen in Java 8 und können abstrakte Methoden sowie Methoden mit Standardimplementierung enthalten. Klassen können eine oder mehrere Schnittstellen implementieren.
interface Drawable {
fun draw() // Abstrakte Methode
fun description() { // Methode mit Standardimplementierung
println("Dies ist ein zeichnungsfähiges Objekt")
}
}
class Square : Drawable {
override fun draw() { // Implementierung der abstrakten Methode
println("Zeichne ein Quadrat")
}
// description() kann überschrieben werden, ist aber nicht erforderlich
}
Polymorphismus:
Polymorphismus in Kotlin wird durch die Fähigkeit erreicht, mit Objekten verschiedener Klassen über einen gemeinsamen Basistyp (Klasse oder Schnittstelle) zu arbeiten. Dadurch können Methoden aufgerufen werden, die spezifisch für den tatsächlichen Objekttyp sind, zur Laufzeit.
fun render(drawable: Drawable) {
drawable.draw() // Ruft die draw() Methode je nach tatsächlichem Objekttyp auf
drawable.description()
}
fun main() {
val circle: Shape = Circle() // Objekt Circle wird als Shape behandelt
circle.draw() // Ruft die draw() von Circle aufgrund des Polymorphismus auf
val square: Drawable = Square() // Objekt Square wird als Drawable behandelt
render(square) // Ruft draw() und description() von Square auf
}
In diesem Beispiel arbeitet render mit jedem Objekt, das Drawable implementiert. Der Aufruf drawable.draw() führt die Implementierung der Methode draw für den konkreten Objekttyp aus (Square in diesem Fall).
Unterschiede zwischen Klassenvererbung und Schnittstellenimplementierung:
- Klassenvererbung: Stellt eine "ist-ein"-Beziehung her (is-a). Die Kindklasse erbt Zustand und Verhalten der Basisklasse.
- Schnittstellenimplementierung: Definiert eine "Fähigkeit" oder einen "Vertrag". Die Klasse verspricht, die Implementierung aller abstrakten Methoden der Schnittstelle bereitzustellen.
Vergleichstabelle:
| Eigenschaft | Klassenvererbung | Schnittstellenimplementierung |
|---|---|---|
| Beziehungstyp | ist-ein (is-a) | Fähigkeit / Vertrag |
| Mehrfachvererbung | Einzelvererbung | Mehrfachvererbung |
| Zustand | Erbt Zustand der Basisklasse | Erbt keinen Zustand |
| Methodenimplementierung | Kann Implementierung enthalten | Kann Standardimplementierung haben (ab Java 8) |