Schnittstellen deklarieren
Teil des Abschnitts Objektorientierte Programmierung der Kotlin-Journey von Coddy. Lektion 22 von 57.
Ein Interface listet auf, was ein Typ tun kann, ohne zu sagen, wie. Es deklariert Methoden und Eigenschaften, die jede implementierende Klasse bereitstellen muss. Eine Klasse implementiert ein Interface mit einem Doppelpunkt, wie bei einer Oberklasse, jedoch ohne Klammern, da ein Interface keinen Konstruktor hat:
interface Drawable {
fun draw(): String
}
class Circle(val radius: Int) : Drawable {
override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
override fun draw() = "-".repeat(length)
}Innerhalb von main:
println(Circle(3).draw())
println(Line(5).draw())Ausgabe:
circle with radius 3
-----Eine Schnittstelle kann ebenfalls Eigenschaften deklarieren. Die Klasse stellt sie als Konstruktor-Eigenschaften, gespeicherte Eigenschaften oder Getter bereit; die Schnittstelle selbst speichert nichts:
interface Vehicle {
val wheels: Int
val label: String
}
class Car(override val label: String) : Vehicle {
override val wheels = 4
}
class Bike : Vehicle {
override val wheels = 2
override val label: String
get() = "bike on $wheels wheels"
}Innerhalb von main:
println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)Ausgabe:
taxi: 4
bike on 2 wheelsJedes von der Schnittstelle deklarierte Mitglied muss implementiert werden, jeweils mit override, andernfalls wird die Klasse nicht kompiliert. Eine Schnittstelle kann nicht instanziiert werden:
interface Speaker {
fun speak(): String
val volume: Int
}
// class Mute : Speaker { override fun speak() = "" } // Fehler: volume ist nicht implementiert
// class Loud : Speaker() { ... } // Fehler: ein Interface hat keinen Konstruktor
// val s = Speaker() // Fehler: ein Interface kann nicht erstellt werdenEine Schnittstelle und eine abstrakte Klasse deklarieren beide Member ohne Rumpf. Eine Schnittstelle hat keinen Konstruktor und keinen gespeicherten Zustand, und eine Klasse kann viele Schnittstellen implementieren, aber nur eine Klasse erweitern. Verwende eine Schnittstelle für eine Fähigkeit, die voneinander unabhängige Klassen gemeinsam haben, etwa Drawable oder Comparable, und eine abstrakte Klasse als gemeinsame Basisklasse mit Zustand.
interface Drawable { fun draw(): String } // eine Fähigkeit
abstract class Shape(val name: String) { abstract fun area(): Double } // eine Basis mit Zustand
class Square(val s: Double) : Shape("square"), Drawable { // eine Klasse, beliebige Interfaces
override fun area() = s * s
override fun draw() = "[]"
}Aufgabe
EinfachDeklariere die Mitglieder des Interfaces Shape: eine schreibgeschützte Eigenschaft name sowie die Methoden area() und perimeter(), die beide Double zurückgeben. Lasse Rectangle(width, height) (Name rectangle) und Circle(radius) (Name circle, unter Verwendung von Math.PI) diese implementieren. Vervollständige anschließend describe(shape), das mit zwei Dezimalstellen unter Verwendung ausschließlich der Mitglieder von Shape rectangle: area 12.00, perimeter 14.00 zurückgibt.
Der bereitgestellte Code liest Zeilen wie r,3,4 oder c,2, erstellt die passende Form und gibt describe(shape) aus.
Dein Code gehört in Shape.kt, Rectangle.kt, Circle.kt und Functions.kt. Main.kt enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
fun main() {
// Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
val input = generateSequence(::readLine).toList()
for (line in input) {
val p = line.split(",").map { it.trim() }
val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
println(describe(shape))
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenPrimärkonstruktoreninit-Blöcke und ValidierungSekundärkonstruktorenRückblick – Bibliotheksausweis4Vererbung
Offene Klassen und UnterklassenÜberschreiben von Membernsuper und KonstruktorenAbstrakte KlassenRückblick – Mitarbeiterverzeichnis2Eigenschaften und Kapselung
Benutzerdefinierte ZugriffsmethodenSichtbarkeitsmodifikatorenPrivate Setterlazy und lateinitWiederholung – Bankkonto5Schnittstellen
Schnittstellen deklarierenStandardmethodenMehrere SchnittstellenSchnittstellen als TypenRückblick – Zahlungsmethoden8Generics
Generische FunktionenGenerische KlassenTypbeschränkungenVarianz mit in und outRückblick – Prioritätswarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Kotlin-Playground