Datenklassen
Teil des Abschnitts Objektorientierte Programmierung der Kotlin-Journey von Coddy. Lektion 32 von 57.
Eine Datenklasse ist eine Klasse, deren Hauptaufgabe darin besteht, Daten zu speichern. Der Modifikator data veranlasst den Compiler, toString(), equals(), hashCode(), copy() und componentN() aus den Eigenschaften des primären Konstruktors zu generieren:
data class Point(val x: Int, val y: Int)Innerhalb von main:
val a = Point(1, 2)
val b = Point(1, 2)
println(a)
println(a == b)
println(setOf(a, b).size)Ausgabe:
Point(x=1, y=2)
true
1Ohne data zeigt println den Klassennamen und einen Hashcode wie Point@1b6d3586 an, und zwei Objekte mit denselben Werten sind nicht gleich. copy() erstellt ein neues Objekt, bei dem einige Eigenschaften geändert wurden, und lässt das ursprüngliche Objekt unverändert, sodass eine Datenklasse mit val-Eigenschaften als unveränderlicher Wert funktioniert:
data class User(val name: String, val email: String, val admin: Boolean = false)Innerhalb von main:
val ada = User("Ada", "ada@example.com")
val boss = ada.copy(admin = true)
println(ada)
println(boss)
println(ada == boss)Ausgabe:
User(name=Ada, email=ada@example.com, admin=false)
User(name=Ada, email=ada@example.com, admin=true)
falseDestrukturierungsdeklarationen packen ein Objekt in Variablen aus: val (x, y) = point ruft die generierten Methoden component1() und component2() in der Reihenfolge des Konstruktors auf. Dies funktioniert auch in for-Schleifen und Lambda-Parametern, und _ überspringt eine Eigenschaft:
data class Score(val player: String, val points: Int, val level: Int)Innerhalb von main:
val scores = listOf(Score("ada", 120, 3), Score("bo", 95, 2))
for ((player, points) in scores) println("$player: $points")
val (_, bestPoints, bestLevel) = scores.maxBy { it.points }
println("best: $bestPoints at level $bestLevel")Ausgabe:
ada: 120
bo: 95
best: 120 at level 3Nur Eigenschaften des Primärkonstruktors werden berücksichtigt: Eine im Klassenkörper deklarierte Eigenschaft wird bei toString, equals, hashCode und copy ausgelassen. Eine Datenklasse benötigt mindestens einen Konstruktorparameter, und jeder Parameter muss ein val oder var sein:
data class Reading(val sensor: String, val value: Int) {
var note = ""
}Innerhalb von main:
val r1 = Reading("t1", 20)
val r2 = Reading("t1", 20)
r1.note = "checked"
println(r1)
println(r1 == r2)Ausgabe:
Reading(sensor=t1, value=20)
trueAufgabe
EinfachMach Book zu einer Datenklasse, damit sie nach ihrem Wert ausgegeben und verglichen wird. Vervollständige dann drei Funktionen: parse(line) wandelt Dune;Herbert;1965 in ein Book um, newEdition(book, year) gibt eine Kopie mit dem neuen Jahr und (new edition) im Titel zurück, und describe(book) gibt mithilfe einer Destrukturierungsdeklaration Dune by Herbert, 1965 zurück.
Der bereitgestellte Code verarbeitet jede Eingabezeile, gibt jedes Buch, die Anzahl der Duplikate, die neue Ausgabe des ersten Buchs (Jahr 2024) und eine Beschreibung jedes unterschiedlichen Buchs aus.
Dein Code gehört in Book.kt und BookTools.kt. Main.kt enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
fun main() {
// Bereitgestellter Ein-/Ausgabecode: belasse ihn wie er ist
val input = generateSequence(::readLine).toList()
val books = input.map { parse(it) }
for (b in books) println(b)
println("duplicates: ${books.size - books.distinct().size}")
println(newEdition(books[0], 2024))
for (b in books.distinct()) println(describe(b))
}
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 – Mitarbeiterverzeichnis7Spezielle Klassen
DatenklassenEnum-KlassenVersiegelte Hierarchienequals, hashCode, toStringRückblick – Bestellverfolgung2Eigenschaften 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