Klassen erstellen
Sie können nicht nur vordefinierte Typen wie
IntRangeundStringverwenden, sondern auch Ihre eigenen Objekttypen erstellen.
Tatsächlich besteht ein Großteil der Aktivitäten in der objektorientierten Programmierung darin, neue Typen zu erstellen. Sie erstellen neue Typen, indem Sie Klassen definieren.
Ein Objekt ist ein Teil der Lösung für ein Problem, das Sie zu lösen versuchen. Beginnen Sie damit, Objekte als Ausdruck von Konzepten zu betrachten. Als erste Annäherung, wenn Sie ein “Ding” in Ihrem Problem entdecken, repräsentieren Sie dieses Ding als Objekt in Ihrer Lösung.
Angenommen, Sie möchten ein Programm erstellen, um Tiere in einem Zoo zu verwalten. Es ist sinnvoll,
die verschiedenen Tierarten basierend darauf zu kategorisieren, wie sie sich verhalten, welche Bedürfnisse sie haben, mit welchen Tieren sie sich vertragen und mit welchen sie kämpfen. Alles, was eine Tierart unterscheidet, wird in der Klassifizierung des Objekts dieses Tieres erfasst. Kotlin verwendet das Schlüsselwort class, um einen neuen Objekttyp zu erstellen:
// CreatingClasses/Animals.kt
// Create some classes:
class Giraffe
class Bear
class Hippo
fun main() {
// Create some objects:
val g1 = Giraffe()
val g2 = Giraffe()
val b = Bear()
val h = Hippo()
// Each object() is unique:
println(g1)
println(g2)
println(h)
println(b)
}
/* Sample output:
Giraffe@28d93b30
Giraffe@1b6d3586
Hippo@4554617c
Bear@74a14482
*/
Um eine Klasse zu definieren, beginnen Sie mit dem Schlüsselwort class, gefolgt von einem Bezeichner für Ihre neue Klasse. Der Klassenname muss mit einem Buchstaben (A-Z, Groß- oder Kleinbuchstaben) beginnen, kann jedoch Zahlen und Unterstriche enthalten. Nach Konvention wird der erste Buchstabe eines Klassennamens großgeschrieben, während der erste Buchstabe aller vals und vars kleingeschrieben wird.
Animals.kt beginnt mit der Definition von drei neuen Klassen und erstellt dann vier Objekte (auch Instanzen genannt) dieser Klassen.
Giraffe ist eine Klasse, aber eine bestimmte fünfjährige männliche Giraffe, die in Botswana lebt, ist ein Objekt. Jedes Objekt unterscheidet sich von allen anderen, daher geben wir ihnen Namen wie g1 und g2.
Beachten Sie die etwas kryptische Ausgabe der letzten vier Zeilen. Der Teil vor dem @ ist der Klassenname und die Zahl nach dem @ ist die Adresse, an der sich das Objekt im Speicher Ihres Computers befindet. Ja, das ist eine Zahl, auch wenn sie einige Buchstaben enthält - das nennt man “hexadezimale Notation”. Jedes Objekt in Ihrem Programm hat seine eigene eindeutige Adresse.
Die hier definierten Klassen (Giraffe, Bear und Hippo) sind so einfach wie möglich: die gesamte Klassendefinition besteht aus einer einzigen Zeile. Komplexere Klassen verwenden geschweifte Klammern ({ und }), um einen Klassenkörper zu erstellen, der die Merkmale und Verhaltensweisen dieser Klasse enthält.
Eine innerhalb einer Klasse definierte Funktion gehört zu dieser Klasse. In Kotlin nennen wir sie Mitgliedsfunktionen der Klasse. Einige objektorientierte Programmiersprachen wie Java entscheiden sich dafür, sie Methoden zu nennen, ein Begriff, der aus frühen objektorientierten Sprachen wie Smalltalk stammt. Um die funktionale Natur von Kotlin zu betonen, entschieden sich die Designer, den Begriff Methode wegzulassen, da einige Anfänger die Unterscheidung verwirrend fanden. Stattdessen wird in der gesamten Sprache der Begriff Funktion verwendet.
Wenn es eindeutig ist, sagen wir einfach “Funktion”. Wenn wir die Unterscheidung treffen müssen:
- Mitgliedsfunktionen gehören zu einer Klasse.
- Top-Level-Funktionen existieren für sich und sind nicht Teil einer Klasse.
Hier gehört bark() zur Dog-Klasse:
// CreatingClasses/Dog.kt
class Dog {
fun bark() = "yip!"
}
fun main() {
val dog = Dog()
}
In main() erstellen wir ein Dog-Objekt und weisen es val dog zu. Kotlin gibt eine Warnung aus, weil wir dog nie verwenden.
Mitgliedsfunktionen werden aufgerufen (invoked), indem man den Objektnamen verwendet, gefolgt von einem . (Punkt), gefolgt vom Funktionsnamen und der Parameterliste. Hier rufen wir die Funktion meow() auf und zeigen das Ergebnis an:
// CreatingClasses/Cat.kt
class Cat {
fun meow() = "mrrrow!"
}
fun main() {
val cat = Cat()
// Call 'meow()' for 'cat':
val m1 = cat.meow()
println(m1)
}
/* Output:
mrrrow!
*/
Eine Mitgliedsfunktion wirkt auf eine bestimmte Instanz einer Klasse. Wenn Sie meow() aufrufen, müssen Sie es mit einem Objekt aufrufen. Während des Aufrufs kann meow() auf andere Mitglieder dieses Objekts zugreifen.
Beim Aufrufen einer Mitgliedsfunktion verfolgt Kotlin das betreffende Objekt, indem es leise eine Referenz auf dieses Objekt übergibt. Diese Referenz ist innerhalb der Mitgliedsfunktion mit dem Schlüsselwort this verfügbar.
Mitgliedsfunktionen haben einen speziellen Zugriff auf andere Elemente innerhalb einer Klasse, indem sie einfach diese Elemente benennen. Sie können den Zugriff auf diese Elemente auch explizit mit this qualifizieren. Hier ruft exercise() speak() mit und ohne Qualifizierung auf:
// CreatingClasses/Hamster.kt
class Hamster {
fun speak() = "Squeak! "
fun exercise() =
this.speak() + // Qualified with 'this'
speak() + // Without 'this'
"Running on wheel"
}
fun main() {
val hamster = Hamster()
println(hamster.exercise())
}
/* Output:
Squeak! Squeak! Running on wheel
*/
In exercise(), rufen wir zuerst speak() mit einem expliziten this auf und lassen dann die Qualifikation weg.
Manchmal sieht man Code, der ein unnötiges explizites this enthält. Solcher Code stammt oft von Programmierern, die eine andere Sprache kennen, in der this entweder erforderlich ist oder Teil des Stils ist. Die unnötige Verwendung eines Features ist verwirrend für den Leser, der Zeit damit verbringt, herauszufinden, warum Sie es tun. Wir empfehlen, die unnötige Verwendung von this zu vermeiden.
Außerhalb der Klasse muss man hamster.exercise() und hamster.speak() sagen.
Übungen und Lösungen finden Sie auf www.AtomicKotlin.com.