Dieses Codelab ist Teil des Kotlin-Bootcamps für Programmierer. Sie profitieren von diesem Kurs, wenn Sie nacheinander die Codelabs durcharbeiten. Abhängig von Ihrem Wissen können Sie möglicherweise einige Abschnitte überfliegen. Dieser Kurs richtet sich an Programmierer, die eine objektorientierte Sprache kennen und Kotlin lernen möchten.
Einführung
In diesem Codelab erstellen Sie ein Kotlin-Programm und erfahren mehr über Klassen und Objekte in Kotlin. Die meisten Inhalte sind Ihnen bekannt, wenn Sie eine andere objektorientierte Sprache kennen. Kotlin unterscheidet sich aber in einigen wichtigen Punkten, sodass Sie weniger Code schreiben müssen. Außerdem erfahren Sie mehr über abstrakte Klassen und die Delegierung von Benutzeroberflächen.
Anstatt eine einzige Beispiel-App zu entwickeln, sollten die Lektionen in diesem Kurs auf Ihrem Wissen aufbauen. Sie sind aber unabhängig und können die einzelnen Abschnitte überfliegen. In vielen Beispielen sehen Sie ein Aquarium. Wenn Sie die ganze Geschichte des Aquariums sehen möchten, sollten Sie sich den Kotlin Bootcamp für Programmers Udacity ansehen.
Was Sie bereits wissen sollten
- Grundlagen von Kotlin, einschließlich Typen, Operatoren und Loopings
- Syntax der Kotlin-Funktionen
- Grundlagen der objektorientierten Programmierung
- Grundlagen einer IDE wie IntelliJ IDEA oder Android Studio
Lerninhalte
- In Kotlin Klassen erstellen und auf Properties zugreifen
- Klassenkonstrukter in Kotlin erstellen und verwenden
- Unterklasse erstellen und Funktionsweise der Übernahme
- Abstrakte Klassen, Schnittstellen und Schnittstellendelegierung
- Datenklassen erstellen und verwenden
- Singleton-Werte, Aufzählungen und versiegelte Klassen verwenden
Aufgaben
- Klasse mit Attributen erstellen
- Konstruktor für eine Klasse erstellen
- Unterklasse erstellen
- Beispiele für abstrakte Klassen und Schnittstellen untersuchen
- Einfache Datenklasse erstellen
- Weitere Informationen zu Singleton- und Aufzählungslisten sowie zu versiegelten Klassen
Die folgenden Programmierkenntnisse sollten Ihnen bereits vertraut sein:
- Klassen sind Baupläne für Objekte. Eine
Aquarium
-Klasse ist beispielsweise der Bauplan für ein Aquariumobjekt. - Objekte sind Instanzen von Klassen. Ein Aquariumobjekt ist ein tatsächlicher
Aquarium
. - Attribute sind Eigenschaften von Klassen, z. B. Länge, Breite und Höhe eines
Aquarium
. - Methoden, auch als Mitgliederfunktionen bezeichnet, sind die Funktionen der Klasse. Methoden können mit dem Objekt verwendet werden. Du kannst beispielsweise ein
Aquarium
-ObjektfillWithWater()
. - Eine Schnittstelle ist eine Spezifikation, die eine Klasse implementieren kann. Beispiel: Die Reinigung ist häufig für andere Objekte als Aquarien üblich. Die Reinigung erfolgt im Allgemeinen auf ähnliche Weise für verschiedene Objekte. So könnte eine Schnittstelle namens
Clean
die Definition einerclean()
-Methode definieren. Mit der KlasseAquarium
kann die SchnittstelleClean
implementiert werden, um das Aquarium mit einem weichen Schwamm zu reinigen. - Pakete sind eine Möglichkeit, verwandten Code zu gruppieren, um ihn zu organisieren oder eine Codebibliothek zu erstellen. Nachdem ein Paket erstellt wurde, können Sie den Inhalt des Pakets in eine andere Datei importieren und den Code und die Klassen in diesem Paket wiederverwenden.
In dieser Aufgabe erstellen Sie ein neues Paket und eine Klasse mit einigen Attributen und einer Methode.
Schritt 1: Paket erstellen
Mit Paketen können Sie Ihren Code besser organisieren.
- Klicken Sie im Bereich Projekt unter dem Projekt Hello Kotlin mit der rechten Maustaste auf den Ordner src.
- Wähle New > Package aus und rufe es
example.myapp
auf.
Schritt 2: Klasse mit Properties erstellen
Klassen werden mit dem Keyword class
definiert, wobei die Klassennamen per Konvention mit einem Großbuchstaben beginnen.
- Klicken Sie mit der rechten Maustaste auf das Paket example.myapp.
- Wähle Neu > Kotlin-Datei / Klasse aus.
- Wählen Sie unter Art die Option Kurs aus und nennen Sie die Klasse
Aquarium
. IntelliJ IDEA enthält den Paketnamen in der Datei und erstellt eine leereAquarium
-Klasse. - Definieren und initialisieren Sie innerhalb der
Aquarium
-Klasse dievar
-Eigenschaften für Breite, Höhe und Länge (in Zentimetern). Initialisieren Sie die Eigenschaften mit Standardwerten.
package example.myapp
class Aquarium {
var width: Int = 20
var height: Int = 40
var length: Int = 100
}
Im Hintergrund werden mit Kotlin automatisch Getter und Setter für die Properties erstellt, die Sie in der Aquarium
-Klasse definiert haben. So können Sie direkt auf die Properties zugreifen, zum Beispiel „myAquarium.length
“.
Schritt 3: „main()“-Funktion erstellen
Erstelle eine neue Datei mit dem Namen main.kt
, die die Funktion main()
enthalten soll.
- Klicken Sie links im Bereich Projekt mit der rechten Maustaste auf das Paket beispiel.meineapp.
- Wähle Neu > Kotlin-Datei / Klasse aus.
- Behalten Sie im Drop-down-Menü Art die Option Datei bei und benennen Sie die Datei
main.kt
. IntelliJ IDEA enthält den Paketnamen, aber keine Klassendefinition für eine Datei. - Definieren Sie eine
buildAquarium()
-Funktion und erstellen Sie darin eine Instanz vonAquarium
. Verweisen Sie zum Erstellen einer Instanz auf die Klasse, als wäre sie eine Funktion,Aquarium()
. Dadurch wird der Konstruktor der Klasse aufgerufen und eine Instanz der KlasseAquarium
erstellt, ähnlich wie beinew
in anderen Sprachen. - Definiere eine
main()
-Funktion und rufebuildAquarium()
auf.
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium()
}
fun main() {
buildAquarium()
}
Schritt 4: Methode hinzufügen
- Fügen Sie in der Klasse
Aquarium
eine Methode hinzu, um die Eigenschaften des Aquariums zu drucken.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
}
- Rufe in
main.kt
inbuildAquarium()
die MethodeprintSize()
fürmyAquarium
auf.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
}
- Führe dein Programm aus, indem du auf das grüne Dreieck neben der Funktion
main()
klickst. Beobachten Sie das Ergebnis.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm
- Fügen Sie in
buildAquarium()
Code hinzu, um die Höhe auf 60 festzulegen und die geänderten Dimensionseigenschaften zu drucken.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
myAquarium.height = 60
myAquarium.printSize()
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 100 cm Height: 60 cm
In dieser Aufgabe erstellen Sie einen Konstruktor für die Klasse und arbeiten weiter mit Attributen.
Schritt 1: Konstruktor erstellen
In diesem Schritt fügen Sie der Klasse Aquarium
, die Sie in der ersten Aufgabe erstellt haben, einen Konstruktor hinzu. Im vorherigen Beispiel wird jede Instanz von Aquarium
mit denselben Dimensionen erstellt. Sie können die Größe nach der Erstellung ändern, indem Sie die Eigenschaften festlegen. Es ist aber einfacher, sie erst einmal mit der richtigen Größe zu erstellen.
In einigen Programmiersprachen wird der Konstruktor durch Erstellen einer Methode innerhalb der Klasse definiert, die denselben Namen wie die Klasse hat. In Kotlin definieren Sie den Konstruktor direkt in der Klassendeklaration. Geben Sie die Parameter in Klammern an, als ob die Klasse eine Methode wäre. Wie bei Funktionen in Kotlin können diese Parameter Standardwerte enthalten.
- Ändern Sie in der zuvor erstellten Klasse
Aquarium
die Klassendefinition, sodass drei Konstruktorparameter mit den Standardwerten fürlength
,width
undheight
enthalten sind. Ordnen Sie sie den entsprechenden Properties zu.
class Aquarium(length: Int = 100, width: Int = 20, height: Int = 40) {
// Dimensions in cm
var length: Int = length
var width: Int = width
var height: Int = height
...
}
- Bei der kompakteren Kotlin-Definition können Sie die Eigenschaften mithilfe von
var
oderval
direkt mit dem Konstruktor definieren. Kotlin erstellt auch die Getter und Setter automatisch. Anschließend können Sie die Property-Definitionen im Hauptbereich der Klasse entfernen.
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40) {
...
}
- Wenn Sie ein
Aquarium
-Objekt mit diesem Konstruktor erstellen, können Sie keine Argumente angeben und die Standardwerte abrufen oder nur einige davon festlegen oder alle festlegen und einAquarium
mit einer benutzerdefinierten Größe erstellen. Probieren Sie in derbuildAquarium()
-Funktion verschiedene Möglichkeiten zum Erstellen einesAquarium
-Objekts mit benannten Parametern aus.
fun buildAquarium() {
val aquarium1 = Aquarium()
aquarium1.printSize()
// default height and length
val aquarium2 = Aquarium(width = 25)
aquarium2.printSize()
// default width
val aquarium3 = Aquarium(height = 35, length = 110)
aquarium3.printSize()
// everything custom
val aquarium4 = Aquarium(width = 25, height = 35, length = 110)
aquarium4.printSize()
}
- Führen Sie das Programm aus und beobachten Sie die Ausgabe.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 25 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 110 cm Height: 35 cm Width: 25 cm Length: 110 cm Height: 35 cm
Sie mussten den Konstruktor nicht überlasten und für jeden dieser Fälle eine andere Version erstellen (für die anderen Kombinationen einige mehr). Kotlin erstellt die erforderlichen Werte aus den Standardwerten und benannten Parametern.
Schritt 2: Sperrblöcke hinzufügen
In den Beispielkonstrukten oben werden nur Eigenschaften deklariert und den Werten eines Ausdrucks zugewiesen. Wenn Ihr Konstruktor mehr Initialisierungscode benötigt, kann er in einem oder mehreren init
-Blöcken platziert werden. In diesem Schritt fügen Sie der Klasse Aquarium
einige init
-Blöcke hinzu.
- Fügen Sie in der Klasse
Aquarium
eineninit
-Block hinzu, damit das Objekt initialisiert wird, und einen zweiten Block, um das Volumen in Liter zu drucken.
class Aquarium (var length: Int = 100, var width: Int = 20, var height: Int = 40) {
init {
println("aquarium initializing")
}
init {
// 1 liter = 1000 cm^3
println("Volume: ${width * length * height / 1000} l")
}
}
- Führen Sie das Programm aus und beobachten Sie die Ausgabe.
aquarium initializing
Volume: 80 l
Width: 20 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 100 l
Width: 25 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 77 l
Width: 20 cm Length: 110 cm Height: 35 cm
aquarium initializing
Volume: 96 l
Width: 25 cm Length: 110 cm Height: 35 cm
Beachten Sie, dass die init
-Blöcke in der Reihenfolge ausgeführt werden, in der sie in der Klassendefinition aufgeführt sind. Alle Blöcke werden ausgeführt, wenn der Konstruktor aufgerufen wird.
Schritt 3: Informationen zu sekundären Konstruktoren
In diesem Schritt erfahren Sie mehr über sekundäre Konstruktoren und fügen Ihrer Klasse einen hinzu. Neben einem primären Konstruktor, der einen oder mehrere init
-Blöcke haben kann, kann eine Kotlin-Klasse auch einen oder mehrere sekundäre Konstruktoren haben, um eine Konstruktorüberlastung zu ermöglichen.
- Füge in der Klasse
Aquarium
einen sekundären Konstruktor hinzu, der mit dem Schlüsselwortconstructor
eine Reihe von Fischen als Argument verwendet. Erstellen Sie eineval
-Tankeigenschaft für das berechnete Volumen des Aquariums in Liter basierend auf der Anzahl der Fische. Nimm 2 Liter Wasser (2.000 cm^3) Wasser pro Fisch sowie ein wenig Extraraum ein, damit das Wasser nicht verschüttet wird.
constructor(numberOfFish: Int) : this() {
// 2,000 cm^3 per fish + extra room so water doesn't spill
val tank = numberOfFish * 2000 * 1.1
}
- Behalten Sie im sekundären Konstruktor die Länge und Breite (im primären Konstruktor) bei und berechnen Sie die Höhe, die für das Erstellen des Tanks erforderlich ist.
// calculate the height needed
height = (tank / (length * width)).toInt()
- Fügen Sie in der Funktion
buildAquarium()
einen Aufruf zum Erstellen einerAquarium
mit Ihrem neuen sekundären Konstruktor ein. Größe und Volumen drucken
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
println("Volume: ${aquarium6.width * aquarium6.length * aquarium6.height / 1000} l")
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ aquarium initializing Volume: 80 l Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
Beachten Sie, dass das Volume zweimal gedruckt wird: einmal durch den init
-Block im primären Konstruktor und vor der Ausführung des sekundären Konstruktors und einmal durch den Code in buildAquarium()
.
Du könntest auch das Keyword constructor
in den primären Konstruktor aufnehmen, aber es ist in den meisten Fällen nicht erforderlich.
Schritt 4: neuen Property Getter hinzufügen
In diesem Schritt fügen Sie einen expliziten Property-Getter hinzu. Wenn Sie Eigenschaften definieren, werden mit Kotlin automatisch Getter und Setter definiert. Manchmal muss jedoch der Wert für eine Eigenschaft angepasst oder berechnet werden. Oben haben Sie z. B. das Volumen von Aquarium
gedruckt. Sie können das Volumen als Property verfügbar machen, indem Sie eine Variable und einen Getter dafür definieren. Da volume
berechnet werden muss, muss der Getter den berechneten Wert zurückgeben. Sie können ihn dazu mit einer einzeiligen Funktion verwenden.
- Definieren Sie in der Klasse
Aquarium
eineInt
-Property mit dem Namenvolume
und definieren Sie eineget()
-Methode, mit der das Volumen in der nächsten Zeile berechnet wird.
val volume: Int
get() = width * height * length / 1000 // 1000 cm^3 = 1 l
- Entfernen Sie den
init
-Block, der die Lautstärke druckt. - Entfernen Sie den Code in
buildAquarium()
, der die Lautstärke druckt. - Fügen Sie in der Methode
printSize()
eine Zeile hinzu, um das Volumen zu drucken.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm "
)
// 1 l = 1000 cm^3
println("Volume: $volume l")
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ aquarium initializing Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
Die Dimensionen und Volumes sind wie zuvor, aber das Volume wird nur einmal gedruckt, nachdem das Objekt sowohl vom primären als auch vom sekundären Konstruktor vollständig initialisiert wurde.
Schritt 5: Property-Setter hinzufügen
In diesem Schritt erstellen Sie einen neuen Property-Setter für das Volume.
- Ändern Sie den
volume
in derAquarium
-Klasse in einenvar
-Wert, damit er mehrmals festgelegt werden kann. - Fügen Sie einen Setter für die Property
volume
hinzu. Fügen Sie dazu unter dem Getter eineset()
-Methode hinzu, die die Höhe basierend auf der angegebenen Wassermenge neu berechnet. Der Name des Setter-Parameters ist standardmäßigvalue
, Sie können ihn aber ändern.
var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
- Fügen Sie in
buildAquarium()
Code hinzu, um die Lautstärke des Aquariums auf 70 Liter festzulegen. Die neue Größe drucken.
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
aquarium6.volume = 70
aquarium6.printSize()
}
- Führen Sie Ihr Programm noch einmal aus und beobachten Sie die geänderte Höhe und Lautstärke.
⇒ aquarium initialized
Width: 20 cm Length: 100 cm Height: 31 cm
Volume: 62 l
Width: 20 cm Length: 100 cm Height: 35 cm
Volume: 70 l
Im Code gab es bislang keine Modifizierer für die Sichtbarkeit wie public
oder private
. Da in Kotlin standardmäßig alles öffentlich ist, können Sie von überall aus darauf zugreifen, einschließlich der Klassen, Methoden, Properties und Mitgliedsvariablen.
In Kotlin können Klassen, Objekte, Schnittstellen, Konstruktoren, Funktionen, Properties und deren Setter Sichtbarkeitsmodifikatoren haben:
public
bedeutet, dass Teilnehmer außerhalb der Klasse sichtbar sind. Alle sind standardmäßig öffentlich, einschließlich Variablen und Methoden der Klasse.internal
bedeutet, dass die Datei nur in diesem Modul sichtbar ist. Ein Modul besteht aus mehreren Kotlin-Dateien, die zusammen zusammengestellt wurden, zum Beispiel aus einer Bibliothek oder Anwendung.private
bedeutet, dass es nur in dieser Klasse (oder Quelldateien, wenn Sie mit Funktionen arbeiten) sichtbar ist.protected
ist identisch mitprivate
, ist aber auch für alle Unterklassen sichtbar.
Weitere Informationen finden Sie in der Kotlin-Dokumentation unter Sichtbarkeitsmodifikatoren.
Mitgliedervariablen
Eigenschaften in einer Klasse oder Mitgliedervariablen sind standardmäßig public
. Wenn Sie sie mit var
definieren, können sie geändert werden, sind also lesbar und beschreibbar. Wenn Sie sie mit val
definieren, sind sie nach der Initialisierung schreibgeschützt.
Wenn Sie eine Property haben, die im Code gelesen oder geschrieben werden kann, während eine externe URL nur Lesevorgänge unterstützt, können Sie die Property und den zugehörigen Getter als öffentlich belassen und den Setter auf „privat“ setzen, wie unten dargestellt.
var volume: Int
get() = width * height * length / 1000
private set(value) {
height = (value * 1000) / (width * length)
}
In dieser Aufgabe lernen Sie, wie Unterklassen und Übernahmen in Kotlin funktionieren. Sie ähneln denen, die du in anderen Sprachen gesehen hast, es gibt aber einige Unterschiede.
In Kotlin können Klassen standardmäßig keine Unterklassen erstellen. Ebenso können Properties und Mitgliedervariablen nicht von Unterklassen überschrieben werden, auf sie kann jedoch zugegriffen werden.
Sie müssen eine Klasse als open
kennzeichnen, damit sie abgeleitet werden kann. Ebenso müssen Sie Attribute und Mitgliedsvariablen als open
markieren, um sie in der Unterklasse zu überschreiben. Das Keyword open
ist erforderlich, um zu vermeiden, dass Daten im Rahmen der Implementierung versehentlich zu Details gelangen.
Schritt 1: Aquarium-Kurs öffnen
In diesem Schritt machen Sie die Aquarium
-Klasse open
, sodass Sie sie im nächsten Schritt überschreiben können.
- Markiere die Klasse
Aquarium
und alle ihre Eigenschaften mit dem Keywordopen
.
open class Aquarium (open var length: Int = 100, open var width: Int = 20, open var height: Int = 40) {
open var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
- Fügen Sie eine offene
shape
-Property mit dem Wert"rectangle"
hinzu.
open val shape = "rectangle"
- Füge eine offene
water
-Property mit einem Getter hinzu, der 90% des Volumens vonAquarium
zurückgibt.
open var water: Double = 0.0
get() = volume * 0.9
- Füge der Methode
printSize()
Code hinzu, um die Form und die Wassermenge als Prozentsatz des Volumens zu drucken.
fun printSize() {
println(shape)
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
// 1 l = 1000 cm^3
println("Volume: $volume l Water: $water l (${water/volume*100.0}% full)")
}
- Ändern Sie in
buildAquarium()
den Code, um einenAquarium
mitwidth = 25
,length = 25
undheight = 40
zu erstellen.
fun buildAquarium() {
val aquarium6 = Aquarium(length = 25, width = 25, height = 40)
aquarium6.printSize()
}
- Führen Sie Ihr Programm aus und beobachten Sie die neue Ausgabe.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full)
Schritt 2: Unterklasse erstellen
- Erstellen Sie eine Unterklasse von
Aquarium
namensTowerTank
, die einen abgerundeten Zylinderbehälter anstelle eines rechteckigen Behälters implementiert. Sie könnenTowerTank
unterAquarium
hinzufügen, da Sie eine weitere Klasse in derselben Datei wie dieAquarium
-Klasse hinzufügen. - Überschreiben Sie in
TowerTank
die Propertyheight
, die im Konstruktor definiert ist. Wenn du eine Property überschreiben möchtest, verwende das Keywordoverride
in der Unterklasse.
- Machen Sie den Konstruktor für
TowerTank
zu einerdiameter
. Verwendediameter
fürlength
undwidth
beim Aufrufen des Konstruktors in derAquarium
-Superclass.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
- Überschreiben Sie die Lautstärke-Property, um einen Zylinder zu berechnen. Die Formel für einen Zylinder ist Pi mal Quadrat des Radius mal die Höhe. Sie müssen die Konstante
PI
ausjava.lang.Math
importieren.
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
- Überschreibe in
TowerTank
das Attributwater
auf 80% des Volumens.
override var water = volume * 0.8
- Überschreibe die Datei
shape
, um"cylinder"
.
override val shape = "cylinder"
- Ihre endgültige
TowerTank
-Klasse sollte in etwa so aussehen:
Aquarium.kt
:
package example.myapp
import java.lang.Math.PI
... // existing Aquarium class
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
override var water = volume * 0.8
override val shape = "cylinder"
}
- Erstellen Sie in
buildAquarium()
einenTowerTank
mit einem Durchmesser von 25 cm und einer Höhe von 45 cm. Drucken Sie das Format aus.
main.kt:
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium(width = 25, length = 25, height = 40)
myAquarium.printSize()
val myTower = TowerTank(diameter = 25, height = 40)
myTower.printSize()
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full) aquarium initializing cylinder Width: 25 cm Length: 25 cm Height: 40 cm Volume: 18 l Water: 14.4 l (80.0% full)
Manchmal möchten Sie gemeinsame Verhaltensweisen oder Eigenschaften definieren, die von verschiedenen zugehörigen Klassen gemeinsam genutzt werden können. Kotlin bietet hierfür zwei Möglichkeiten: Schnittstellen und abstrakte Klassen. In dieser Aufgabe erstellen Sie eine abstrakte AquariumFish
-Klasse für alle Properties, die für alle Fische gelten. Sie erstellen die Benutzeroberfläche FishAction
, um die Funktionsweise aller Fische zu definieren.
- Weder eine abstrakte Klasse noch eine Schnittstelle kann allein instanziiert werden. Das bedeutet, dass Sie keine Objekte dieser Typen direkt erstellen können.
- Abstrakte Klassen haben Konstruktoren.
- Schnittstellen können keine Konstruktorlogik haben oder einen beliebigen Status speichern.
Schritt 1: Abstrakte Klasse erstellen
- Erstellen Sie unter beispiel.meineapp die neue Datei
AquariumFish.kt
. - Erstelle eine Klasse mit dem Namen
AquariumFish
und markiere sie mitabstract
. - Füge eine
String
-Property (color
) hinzu und markiere sie mitabstract
.
package example.myapp
abstract class AquariumFish {
abstract val color: String
}
- Erstelle zwei Unterklassen von
AquariumFish
,Shark
undPlecostomus
. - Da
color
abstrakt ist, müssen die Unterklassen sie implementieren.Shark
wird grau undPlecostomus
Gold.
class Shark: AquariumFish() {
override val color = "gray"
}
class Plecostomus: AquariumFish() {
override val color = "gold"
}
- Erstellen Sie in main.kt eine
makeFish()
-Funktion, um Ihre Kurse zu testen. Instanziiere einenShark
und einenPlecostomus
und drucke dann die Farbe jeder davon aus. - Löschen Sie Ihren vorherigen Testcode in
main()
und fügen SiemakeFish()
einen Aufruf hinzu. Der Code sollte in etwa so aussehen:
main.kt
:
package example.myapp
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
println("Plecostomus: ${pleco.color}")
}
fun main () {
makeFish()
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ Shark: gray Plecostomus: gold
Das folgende Diagramm stellt die Klasse Shark
und die Klasse Plecostomus
dar, die die abstrakte Klasse AquariumFish
darstellt.
Schritt 2: Benutzeroberfläche erstellen
- Erstellen Sie in AquariumFish.kt eine Schnittstelle namens
FishAction
mit der Methodeeat()
.
interface FishAction {
fun eat()
}
- Füge jeder Unterklasse
FishAction
hinzu und implementiereeat()
, indem du sie ausgibst, was die Fische tun sollen.
class Shark: AquariumFish(), FishAction {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
class Plecostomus: AquariumFish(), FishAction {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
- Mit der
makeFish()
Funktion können Sie alle Fische, die Sie erstellt haben, durch Aufrufen voneat()
ernähren.
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
shark.eat()
println("Plecostomus: ${pleco.color}")
pleco.eat()
}
- Führen Sie Ihr Programm aus und beobachten Sie die Ausgabe.
⇒ Shark: gray hunt and eat fish Plecostomus: gold eat algae
Das folgende Diagramm zeigt die Klasse Shark
und die Klasse Plecostomus
, die beide aus der Schnittstelle FishAction
bestehen und implementiert.
Abstrakte Klassen und Schnittstellen verwenden
Die oben genannten Beispiele sind einfach. Aber wenn Sie viele miteinander verbundene Kurse haben, können Sie mithilfe abstrakter Kurse und Benutzeroberflächen Ihr Design sauberer, besser organisieren und einfacher verwalten.
Wie oben erwähnt, können abstrakte Klassen Konstruktoren haben, Schnittstellen können das nicht, ansonsten sind sie sich aber sehr ähnlich. Wann sollten Sie die beiden verwenden?
Wenn Sie Schnittstellen verwenden, um eine Klasse zu erstellen, wird die Funktionalität der Klasse durch die enthaltenen Klasseninstanzen erweitert. Kompositionen erleichtern in der Regel die Wiederverwendung und den Grund dafür, dass sie aus einer abstrakten Klasse übernommen werden können. Sie können in einer Klasse auch mehrere Schnittstellen verwenden, allerdings nur Unterklassen aus einer abstrakten Klasse.
Die Zusammensetzung führt häufig zu einer besseren Kapselung, einer geringeren Kopplung (Interdependenz), einfacheren Schnittstellen und einem besser nutzbaren Code. Aus diesen Gründen wird die Verwendung von Kompositionen mit Schnittstellen bevorzugt. Andererseits ist die Übernahme von einer abstrakten Klasse in der Regel eine natürliche Lösung für einige Probleme. Sie sollten also die Komposition bevorzugen, aber wenn die Übernahme Sinn macht, können Sie das auch mit Kotlin tun.
- Wenn du viele Methoden und eine oder zwei Standardimplementierungen hast, solltest du eine Schnittstelle verwenden, wie in
AquariumAction
unten dargestellt.
interface AquariumAction {
fun eat()
fun jump()
fun clean()
fun catchFish()
fun swim() {
println("swim")
}
}
- Abstrakte Kurse sind immer dann möglich, wenn Sie einen Kurs abgeschlossen haben. Du kannst beispielsweise zur
AquariumFish
-Klasse zurückkehren und die gesamteAquariumFish
-Implementierung aufFishAction
anwenden. Außerdem hast du die Möglichkeit, eine Standardimplementierung füreat
zu implementieren und gleichzeitig die abstrakte Versioncolor
beizubehalten, da es tatsächlich eine Standardfarbe für Fisch gibt.
interface FishAction {
fun eat()
}
abstract class AquariumFish: FishAction {
abstract val color: String
override fun eat() = println("yum")
}
Bei der vorherigen Aufgabe wurden abstrakte Klassen, Benutzeroberflächen und die Idee des Erstellens vorgestellt. Die Schnittstellendelegierung ist eine fortgeschrittene Methode, bei der die Methoden einer Schnittstelle von einem Hilfsobjekt (oder Bevollmächtigten) implementiert werden, das dann von einer Klasse verwendet wird. Das ist nützlich, wenn Sie eine Schnittstelle in einer Reihe unabhängiger Klassen verwenden: Sie fügen die erforderlichen Schnittstellenfunktionen einer separaten Hilfsklasse hinzu, und jede der Klassen verwendet eine Instanz der Hilfsklasse, um die Funktion zu implementieren.
In dieser Aufgabe verwenden Sie die Delegierung der Benutzeroberfläche, um einer Klasse Funktionen hinzuzufügen.
Schritt 1: Neue Benutzeroberfläche erstellen
- Entfernen Sie die Klasse
AquariumFish
in AquariumFish.kt. Anstatt Elemente aus derAquariumFish
-Klasse zu übernehmen, implementierenPlecostomus
undShark
Schnittstellen für die Fischaktion und die jeweilige Farbe. - Erstellen Sie eine neue Schnittstelle,
FishColor
, mit der die Farbe als String definiert wird.
interface FishColor {
val color: String
}
- Ändern Sie
Plecostomus
, um die beiden SchnittstellenFishAction
undFishColor
zu implementieren. Du musstcolor
ausFishColor
undeat()
ausFishAction
überschreiben.
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
- Ändern Sie Ihre
Shark
-Klasse, um auch die beiden SchnittstellenFishAction
undFishColor
zu implementieren, anstatt sie vonAquariumFish
zu übernehmen.
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
- Der fertige Code sollte in etwa so aussehen:
package example.myapp
interface FishAction {
fun eat()
}
interface FishColor {
val color: String
}
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
Schritt 2: Singleton-Kurs erstellen
Als Nächstes implementieren Sie die Einrichtung für den Delegierungsteil, indem Sie eine Hilfsklasse erstellen, die FishColor
implementiert. Sie erstellen die Grundklasse GoldColor
, mit der FishColor
implementiert wird. Sie wird lediglich als Gold bezeichnet.
Es ist nicht sinnvoll, mehrere Instanzen von GoldColor
zu erstellen, da diese Aktionen genau das Gleiche bewirken. Mit Kotlin können Sie also eine Klasse deklarieren, bei der Sie nur eine Instanz davon erstellen können. Nutzen Sie dazu das Keyword object
statt class
. Diese wird von Kotlin erstellt und durch den Klassennamen verwiesen. Alle anderen Objekte können anschließend nur diese eine Instanz verwenden – es ist nicht möglich, andere Instanzen dieser Klasse zu erstellen. Wenn Sie mit dem Singleton-Muster vertraut sind, erfahren Sie, wie Sie Singleton-Modelle in Kotlin implementieren.
- Erstelle in AquariumFish.kt ein Objekt für
GoldColor
. Die Farbe wird überschrieben.
object GoldColor : FishColor {
override val color = "gold"
}
Schritt 3: Schnittstellendelegierung für FishColor hinzufügen
Sie können jetzt die Delegierung der Benutzeroberfläche verwenden.
- Entfernen Sie in AquariumFish.kt die Überschreibung von
color
ausPlecostomus
. - Ändern Sie die Klasse
Plecostomus
, um ihre Farbe ausGoldColor
zu erhalten. Fügen Sie dazuby GoldColor
in die Klassendeklaration ein und erstellen Sie die Delegierung. Das bedeutet, dass anstelle der Implementierung vonFishColor
die vonGoldColor
bereitgestellte Implementierung verwendet wird. Jedes Mal, wenn aufcolor
zugegriffen wird, wird die Instanz anGoldColor
delegiert.
class Plecostomus: FishAction, FishColor by GoldColor {
override fun eat() {
println("eat algae")
}
}
Dabei sind alle Plecos golden, aber diese Fische sind in vielen Farben erhältlich. Sie können das Problem beheben, indem Sie den Konstruktorparameter für die Farbe hinzufügen. Dabei steht GoldColor
als Standardfarbe für Plecostomus
.
- Ändern Sie die Klasse
Plecostomus
so, dass einefishColor
in ihrem Konstruktor übergeben wird, und legen Sie den Standardwert aufGoldColor
fest. Ändern Sie die Delegierung vonby GoldColor
zuby fishColor
.
class Plecostomus(fishColor: FishColor = GoldColor): FishAction,
FishColor by fishColor {
override fun eat() {
println("eat algae")
}
}
Schritt 4: Schnittstellendelegierung für FishAction hinzufügen
Ebenso kannst du die Schnittstellendelegierung für FishAction
verwenden.
- Erstellen Sie in AquariumFish.kt eine
PrintingFishAction
-Klasse, dieFishAction
implementiert, wodurchString
undfood
verwendet werden und dann gedruckt wird, was die Fische essen.
class PrintingFishAction(val food: String) : FishAction {
override fun eat() {
println(food)
}
}
- Entfernen Sie in der
Plecostomus
-Klasse die Überschreibungsfunktioneat()
, da Sie sie durch eine Delegierung ersetzen. - Geben Sie in der Deklaration von
Plecostomus
FishAction
anPrintingFishAction
weiter, um"eat algae"
zu übergeben. - Bei dieser Delegierung gibt es keinen Code im Text der
Plecostomus
-Klasse. Entfernen Sie daher{}
, da alle Überschreibungen von der Schnittstellendelegierung verarbeitet werden
class Plecostomus (fishColor: FishColor = GoldColor):
FishAction by PrintingFishAction("eat algae"),
FishColor by fishColor
Das folgende Diagramm zeigt die Klassen Shark
und Plecostomus
, die beide aus den Schnittstellen PrintingFishAction
und FishColor
bestehen, aber die Implementierung an sie delegieren.
Die Delegierung der Benutzeroberfläche ist leistungsfähig. Wenn Sie eine abstrakte Klasse in einer anderen Sprache nutzen, sollten Sie sich daher überlegen, wie Sie sie einsetzen können. Sie haben die Möglichkeit, die Zusammensetzung zum Starten von Verhaltensweisen zu verwenden, anstatt viele Unterklassen zu konfigurieren, die jeweils unterschiedlich sind.
Eine Datenklasse ähnelt einem struct
-Objekt in einigen anderen Sprachen – sie besteht hauptsächlich aus Daten, doch ein Datenklassenobjekt ist weiterhin ein Objekt. Kotlin-Datenklassenobjekte bieten zusätzliche Vorteile, z. B. Dienstprogramme für das Drucken und Kopieren. In dieser Aufgabe erstellen Sie eine einfache Datenklasse und erfahren, welche Unterstützung Kotlin für Datenklassen bietet.
Schritt 1: Datenklasse erstellen
- Fügen Sie unter dem Paket example.myapp das neue Paket
decor
hinzu, das den neuen Code enthalten soll. Klicken Sie im Bereich Projekt mit der rechten Maustaste auf beispiel.meineapp und wählen Sie Datei > Neues > Paket aus. - Erstellen Sie im Paket eine neue Klasse namens
Decoration
.
package example.myapp.decor
class Decoration {
}
- Wenn
Decoration
eine Datenklasse sein soll, stellen Sie der Klassendeklaration das Keyworddata
voran. - Füge der Property
String
eine Property mit dem Namenrocks
hinzu, damit die Klasse Daten erhält.
data class Decoration(val rocks: String) {
}
- Fügen Sie in der Datei außerhalb der Klasse eine
makeDecorations()
-Funktion hinzu, um eine Instanz vonDecoration
mit"granite"
zu erstellen und zu drucken.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
}
- Fügen Sie eine
main()
-Funktion hinzu, ummakeDecorations()
aufzurufen und das Programm auszuführen. Sie sehen nun die sinnvolle Ausgabe, die erstellt wird, da es sich um eine Datenklasse handelt.
⇒ Decoration(rocks=granite)
- In
makeDecorations()
instanziieren Sie zwei weitereDecoration
-Objekte, die beide &slatiert sind und drucken.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
val decoration2 = Decoration("slate")
println(decoration2)
val decoration3 = Decoration("slate")
println(decoration3)
}
- Fügen Sie in
makeDecorations()
eine Druckausgabe hinzu, in der das Ergebnis des Vergleichs vondecoration1
mitdecoration2
und eines zweiten die Ergebnisse vondecoration3
mitdecoration2
gedruckt werden. Verwenden Sie die von Datenklassen bereitgestellte Methode „Equals()“.
println (decoration1.equals(decoration2))
println (decoration3.equals(decoration2))
- Führen Sie den Code aus.
⇒ Decoration(rocks=granite) Decoration(rocks=slate) Decoration(rocks=slate) false true
Schritt 2: Zerstörende Elemente verwenden
Wenn Sie die Eigenschaften eines Datenobjekts abrufen und Variablen zuweisen möchten, können Sie sie einzeln zuweisen.
val rock = decoration.rock
val wood = decoration.wood
val diver = decoration.diver
Stattdessen können Sie Variablen erstellen, eine für jede Property, und das Datenobjekt der Variablengruppe zuweisen. Kotlin fügt den Property-Wert in jede Variable ein.
val (rock, wood, diver) = decoration
Dieser Begriff wird als Zerstörung bezeichnet und ist ein nützliches Kurzbefehl. Die Anzahl der Variablen sollte der Anzahl der Eigenschaften entsprechen und in der Reihenfolge zugewiesen werden, in der sie in der Klasse deklariert werden. Hier finden Sie ein vollständiges Beispiel für Decoration.kt.
// Here is a data class with 3 properties.
data class Decoration2(val rocks: String, val wood: String, val diver: String){
}
fun makeDecorations() {
val d5 = Decoration2("crystal", "wood", "diver")
println(d5)
// Assign all properties to variables.
val (rock, wood, diver) = d5
println(rock)
println(wood)
println(diver)
}
⇒ Decoration2(rocks=crystal, wood=wood, diver=diver) crystal wood diver
Wenn du eine oder mehrere Properties nicht benötigst, kannst du sie mit _
anstelle des Variablennamens überspringen, wie im Code unten zu sehen ist.
val (rock, _, diver) = d5
In dieser Aufgabe lernen Sie einige der Spezialklassen in Kotlin kennen, darunter:
- Singleton-Kurse
- Enums
- Versiegelte Kurse
Schritt 1: Singleton-Klassen wiederholen
Rufen Sie das vorherige Beispiel mit der Klasse GoldColor
auf.
object GoldColor : FishColor {
override val color = "gold"
}
Da jede Instanz von GoldColor
dasselbe macht, wird sie als object
anstelle von class
deklariert, um sie zu einem Singleton zu machen. Es kann nur einmal vorkommen.
Schritt 2: Aufzählung erstellen
Kotlin unterstützt auch Aufzählungen. Damit können Sie etwas aufzählen und darauf verweisen, ähnlich wie in anderen Sprachen. Deklarieren Sie eine Aufzählung, indem Sie der Deklaration das Keyword enum
voranstellen. Für eine einfache enum-Deklaration ist nur eine Liste von Namen erforderlich. Sie können aber auch ein oder mehrere mit jedem Namen verknüpfte Felder definieren.
- In Decoration.kt können Sie ein Beispiel für eine Aufzählung ausprobieren.
enum class Color(val rgb: Int) {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
}
Aufzählungen sind ein wenig wie Singletons – es kann nur eine und nur jeweils einen Wert in der Aufzählung geben. Es kann beispielsweise nur ein Color.RED
-, ein Color.GREEN
- und ein Color.BLUE
-Element geben. In diesem Beispiel werden die RGB-Werte der rgb
-Property zugewiesen, um die Farbkomponenten darzustellen. Du kannst auch den Ordinalwert einer Aufzählung in der ordinal
-Property und deren Namen in der name
-Property abrufen.
- Versuchen Sie es mit einem anderen Beispiel einer Aufzählung.
enum class Direction(val degrees: Int) {
NORTH(0), SOUTH(180), EAST(90), WEST(270)
}
fun main() {
println(Direction.EAST.name)
println(Direction.EAST.ordinal)
println(Direction.EAST.degrees)
}
⇒ EAST 2 90
Schritt 3: Versiegelte Kurse erstellen
Eine versiegelte Klasse ist eine Klasse, die abgeleitet werden kann, aber nur innerhalb der Datei, in der sie deklariert wird. Wenn Sie versuchen, die Klasse in einer anderen Datei zu unterteilen, erhalten Sie eine Fehlermeldung.
Da sich die Klassen und Unterklassen in derselben Datei befinden, kennt Kotlin alle Unterklassen statisch. Bei der Kompilierung erkennt der Compiler also alle Klassen und abgeleiteten Klassen und weiß, dass dies alle sind. Deshalb kann er zusätzliche Prüfungen durchführen.
- Testen Sie in AquariumFish.kt ein Beispiel für eine versiegelte Unterrichtsklasse, die mit dem Wasserthema zusammenhängt.
sealed class Seal
class SeaLion : Seal()
class Walrus : Seal()
fun matchSeal(seal: Seal): String {
return when(seal) {
is Walrus -> "walrus"
is SeaLion -> "sea lion"
}
}
Die Seal
-Klasse kann in einer anderen Datei nicht abgeleitet werden. Wenn Sie weitere Seal
-Typen hinzufügen möchten, müssen Sie dies in derselben Datei tun. So sind geschützte Klassen eine sichere Möglichkeit, um eine feste Anzahl bestimmter Typen darzustellen. Versiegelte Kurse eignen sich beispielsweise hervorragend, um Erfolge oder Fehler von einer Netzwerk-API zurückzugeben.
In dieser Lektion wurden viele Themen behandelt. Auch wenn viele der Tools von anderen objektorientierten Programmiersprachen vertraut sein sollten, werden von Kotlin einige Funktionen hinzugefügt, die den Code kurz und verständlich halten.
Klassen und Konstruktoren
- Definieren Sie eine Klasse in Kotlin mit
class
. - Kotlin erstellt automatisch Setter und Getter für Properties.
- Definieren Sie den primären Konstruktor direkt in der Klassendefinition. Beispiel:
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40)
- Wenn ein primärer Konstruktor weiteren Code benötigt, schreiben Sie ihn in einen oder mehrere
init
-Blöcke. - Mit
constructor
können in einer Klasse ein oder mehrere Konstruktoren definiert werden. Der Kotlin-Stil wird jedoch verwendet, stattdessen wird eine Factory-Funktion verwendet.
Sichtbarkeitsmodifikatoren und Unterklassen
- Standardmäßig sind alle Klassen und Funktionen in Kotlin „
public
“. Sie können aber Modifikatoren verwenden, um die Sichtbarkeit in „internal
“, „private
“ oder „protected
“ zu ändern. - Wenn Sie eine untergeordnete Klasse erstellen möchten, muss die übergeordnete Klasse als
open
gekennzeichnet sein. - Wenn Sie Methoden und Eigenschaften in einer Unterklasse überschreiben möchten, müssen sie in der übergeordneten Klasse mit
open
gekennzeichnet sein. - Eine versiegelte Klasse kann nur in der Datei abgeleitet werden, in der sie definiert wurde. Versiegeln Sie eine versiegelte Klasse, indem Sie der Deklaration das Präfix
sealed
voranstellen.
Datenklassen, Singleton-Werte und Aufzählungen
- Erstellen Sie eine Datenklasse, indem Sie der Deklaration das Präfix
data
voranstellen. - Zerstörende ist eine Verknüpfung zum Zuweisen der Eigenschaften eines
data
-Objekts zu separaten Variablen. - Erstellen Sie eine Singleton-Klasse mithilfe von
object
stattclass
. - Erstelle eine Aufzählung mit
enum class
.
Abstrakte Klassen, Schnittstellen und Delegierung
- Abstrakte Klassen und Schnittstellen sind zwei Möglichkeiten, um das Verhalten zwischen Klassen gemeinsam zu nutzen.
- Eine abstrakte Klasse definiert Eigenschaften und Verhalten, aber die Implementierung bleibt Unterklassen vorbehalten.
- Eine Schnittstelle definiert das Verhalten und kann Standardimplementierungen für einen Teil oder das gesamte Verhalten bereitstellen.
- Wenn Sie Schnittstellen verwenden, um eine Klasse zu erstellen, wird die Funktionalität der Klasse durch die enthaltenen Klasseninstanzen erweitert.
- Bei der Delegierung der Schnittstelle wird die Zusammensetzung verwendet, aber auch die Implementierung wird an die Klassenklassen delegiert.
- Die Komposition ist eine leistungsstarke Möglichkeit, um mithilfe der Schnittstellendelegierung Funktionen zu einer Klasse hinzuzufügen. Im Allgemeinen ist es vorzuziehen, eine Komposition von einer abstrakten Klasse zu übernehmen, aber einige Probleme sind in diesem Fall besser geeignet.
Kotlin-Dokumentation
Wenn Sie weitere Informationen zu einem Thema in diesem Kurs benötigen oder nicht mehr weiterkommen, ist https://kotlinlang.org der beste Ausgangspunkt.
- Klassen und Übernahme
- Konstrukteur
- Factory-Funktionen
- Eigenschaften und Felder
- Sichtbarkeitsmodifikatoren
- Zusammenfassungsklassen
- Schnittstellen
- Delegierung
- Datenklassen
- Gleichheit
- Zerstörende
- Objektdeklarationen
- Enum-Klassen
- Versiegelte Kurse
- Umgang mit optionalen Fehlern mithilfe von Kotlin-Versiegelten Klassen
Kotlin-Anleitungen
Auf der Website https://try.kotlinlang.org finden Sie umfassende Anleitungen mit dem Namen Kotlin Koans, einem webbasierten Interpreter und eine umfassende Referenz mit Beispielen.
Udacity-Kurs
Informationen zum Udacity-Kurs zu diesem Thema finden Sie im Kotlin-Bootcamp für Programmierer.
IntelliJ IDEA
Die Dokumentation für IntelliJ IDEA finden Sie auf der JetBrains-Website.
In diesem Abschnitt werden mögliche Hausaufgaben für Schüler oder Studenten aufgeführt, die an diesem von einem Kursleiter geleiteten Codelab arbeiten. Die Lehrkraft kann Folgendes tun:
- Bei Bedarf können Sie die entsprechenden Aufgaben zuweisen.
- Schülern mitteilen, wie sie Aufgaben für die Aufgabe abgeben
- Benoten Sie die Hausaufgaben.
Lehrkräfte können diese Vorschläge so oft oder so oft verwenden, wie sie möchten. anderen Aufgaben können sie nach Belieben zugewiesen werden.
Wenn Sie alleine an diesem Codelab arbeiten, können Sie Ihr Wissen mit diesen Hausaufgaben testen.
Diese Fragen beantworten
Frage 1
Klassen haben eine besondere Methode, die als Entwurf zum Erstellen von Objekten dieser Klasse dient. Wie wird die Methode genannt?
▢ Ein Builder
▢ Nutzer
▢ Ein Konstruktor
▢ Entwurf
Frage 2
Welche der folgenden Aussagen zu Schnittstellen und abstrakten Klassen ist NICHT richtig?
▢ Abstrakte Klassen können Konstruktoren haben.
▢ Schnittstellen können keine Konstruktoren haben.
▢ Schnittstellen und abstrakte Klassen können direkt instanziiert werden.
▢ Abstrakte Eigenschaften müssen von Unterklassen der abstrakten Klasse implementiert werden.
Frage 3
Welche der folgenden Optionen ist KEIN Kotlin-Sichtbarkeitsmodifikator für Eigenschaften, Methoden usw.?
▢ internal
▢ nosubclass
▢ protected
▢ private
Frage 4
Ziehen Sie diese Datenklasse in Betracht:data class Fish(val name: String, val species:String, val colors:String)
Welcher der folgenden Werte ist NICHT gültig, um ein Fish
-Objekt zu erstellen und zu destrukturieren?
▢ val (name1, species1, colors1) = Fish("Pat", "Plecostomus", "gold")
▢ val (name2, _, colors2) = Fish("Bitey", "shark", "gray")
▢ val (name3, species3, _) = Fish("Amy", "angelfish", "blue and black stripes")
▢ val (name4, species4, colors4) = Fish("Harry", "halibut")
Frage 5
Angenommen, Sie haben einen Zoo mit vielen Tieren, die sich um alles kümmern müssen. Welche der folgenden Maßnahmen zählt NICHT zur Implementierung der Pflegemaßnahmen?
▢: interface
für verschiedene Arten von Lebensmitteln, die Tiere essen.
▢ Eine abstract Caretaker
-Klasse, aus der Sie verschiedene Arten von Pflegekräften erstellen können.
▢ interface
zur Reinigung von sauberem Wasser.
▢: eine data
-Klasse für einen Eintrag in einem Feedfeed
Fahren Sie mit der nächsten Lektion fort:
Eine Übersicht über den Kurs, einschließlich Links zu anderen Codelabs, findest du im "Kotlin Bootcamp für Programmierer: Kurs.