English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Kotlin Vererbung

In diesem Artikel werden Sie die Vererbung lernen. Genauer gesagt, was ist Vererbung und wie wird Vererbung in Kotlin mit Beispielen implementiert.

Vererbung ist eine der Schlüsselfunktionen der objektorientierten Programmierung. Es ermöglicht es dem Benutzer, eine neue Klasse (Ableitungsklasse) aus einer bestehenden Klasse (Basisklasse) zu erstellen.

Ableitungsklassen übernehmen alle Funktionen der Basisklasse und können zusätzliche Funktionen haben.

Bevor wir das Kotlin-Vererbung in detail erläutern, empfehlen wir Ihnen, die folgenden beiden Artikel zu lesen:

Warum Vererbung?

Angenommen, es sind in Ihrer Anwendung drei Rollen erforderlich-gebenMathematiklehrer(MathTeacher), einenFußballspieler(Footballer) und einenKaufmann(Businessman).

Da alle Rollen Menschen sind, können sie gehen und sprechen. Aber sie haben auch spezielle Fähigkeiten. Der Mathematiklehrer kannMathematik lehren(teachMath)und der Fußballspieler kannFußball spielen(playFootball), der Kaufmann kannUnternehmen führen (runBusiness).

Sie können drei separate Klassen erstellen, die gehen, sprechen und ihre speziellen Fähigkeiten ausführen können.

In jeder Klasse kopieren Sie den gleichen Gehen- und Sprechen-Code für jede Rolle.

Wenn Sie neue Eigenschaften hinzufügen möchten - essen (essen), müssen Sie für jede Rolle denselben Code implementieren. Dies kann leicht zu Fehlern (bei der Kopie) und zur Wiederholung von Code führen.

Wenn wir eine Klasse mit grundlegenden Funktionen wie Person haben, zum Beispiel, gehen, essen, schlafen und spezielle Fähigkeiten für diese Funktionen nach unserer Rolle hinzufügen, wird es einfacher. Dies wird durch Vererbung erreicht.

Mit der Vererbung müssen Sie nicht für jede Klasse das gleiche walk()-, talk()- und eat()-Code implementieren. Sie müssen nurVererbungDas reicht.

Daher können Sie für MathTeacher (Ableitungsklasse) alle Funktionen der Person (Basisklasse) übernehmen und eine neue Funktion teachingMath() hinzufügen. Ebenso können Sie für die Footballer-Klasse alle Funktionen der Person-Klasse übernehmen und die neue Funktion playFootball() hinzufügen, und so weiter.

Das macht Ihren Code kürzer, verständlicher und erweiterbar.

Wichtig ist zu beachten:Bei der Vererbung sollte jede Ableitungsklasse die Bedingungen erfüllen, ob sie eine "Basis"-Klasse ist. Im obigen Beispiel ist MathTeacher eine Person (Mensch), Footballer ist eine Person (Mensch). Man darf nicht denken, dass "Kaufmann(Businessman) gleich Unternehmen(Business)" ist.

Kotlin-Vererbung

Lassen Sie uns versuchen, dies im Code umzusetzen:

offene Klasse Person(age: Int) {
    //Code zum Essen, Sprechen und Gehen
}
class MathTeacher(age: Int): Person(age) {
    //Andere Merkmale des Mathematiklehrers
}
class Footballer(age: Int): Person(age) {
    //Andere Merkmale des Fußballers
}
class Businessman(age: Int): Person(age) {
    // Andere Merkmale des Geschäftsmannes
}

Hier ist Person die Basisklasse, und die Klassen MathTeacher, Footballer und Businessman sind aus der Klasse Person abgeleitet.

Beachtung, der Schlüsselwort open vor der Basisklasse Person ist sehr wichtig.

Standardmäßig sind Klassen in Kotlin final. Wenn Sie Java vertraut sind, dann wissen Sie, dass finalen Klassen keine Ableitungen erlaubt sind. Durch die Verwendung von Annotationen ermöglicht der Compiler die Ableitung neuer Klassen davon.

Beispiel: Kotlin-Vererbung

open class Person(age: Int, name: String) {
    init {
        println("Mein Name ist $name.")
        println("Mein Alter ist $age")
    }
}
class MathTeacher(age: Int, name: String): Person(age, name) {
    fun teachMaths() {
        println("Ich unterrichte in der Grundschule.")
    }
}
class Footballer(age: Int, name: String): Person(age, name) {
    fun playFootball() {
        println("Ich spiele für die Los Angeles Galaxy.")
    }
}
fun main(args: Array<String>) {
    val t1 = MathTeacher(25, "Jack")
    t1.teachMaths()
    println()
    val f1 = Footballer(29, "Christiano")
    f1.playFootball()
}

Wenn das Programm ausgeführt wird, wird die Ausgabe sein:

Mein Name ist Jack.
Mein Alter ist 25
Ich unterrichte in der Grundschule.
Mein Name ist Cristiano.
Mein Alter ist 29
Ich spiele für die Los Angeles Galaxy.

Hier werden zwei Klassen MathTeacher und Footballer aus der Klasse Person abgeleitet.

Die Hauptkonstruktordeklaration der Klasse Person erklärt zwei Attribute: age und name, und hat einen Initialisierungsblock. Die Objekte der Ableitungen der Klasse Person (MathTeacher und Footballer) können den Initialisierungsblock (und die Memberfunktionen) der Basisklasse aufrufen.

Die Ableitungen MathTeacher und Footballer haben各自eigenen Memberfunktionen teachMaths() und playFootball(). Diese Funktionen können nur von den Objekten ihrer eigenen Klassen aufgerufen werden.

wenn ein Objekt der Klasse MathTeacher t erstellt wird1 wenn

val t1 = MathTeacher(25, "Jack")

Parameter werden an den Hauptkonstruktor übergeben. Bei der Erstellung eines Objekts in Kotlin wird der init-Block aufgerufen. Da MathTeacher von der Klasse Person abgeleitet ist, wird der Initialisierungsblock im Basisklasse (Person) gesucht und ausgeführt. Wenn MathTeacher einen init-Block hat, führt der Compiler auch den init-Block der Ableitungsklasse aus.

nächste, um den Ausdruck t1.teachMaths() ruft den Ausdruck t1die Funktion teachMaths() aufruft.

erstellt ein Objekt der Klasse f1 Wenn, dann funktioniert das Programm ähnlich. Es führt den init-Block der Basisklasse aus. Dann wird der Ausdruck f1.playFootball() ruft die Methode playFootball() der Klasse Footballer auf.

Wichtige Anmerkung: Kotlin-Vererbung

  • Wenn die Klasse einen Hauptkonstruktor hat, müssen die Parameter des Hauptkonstruktors zur Initialisierung der Basisklasse verwendet werden. In dem obigen Programm haben beide Ableitungsklassen zwei Parameter age und name, und beide Parameter werden im Hauptkonstruktor der Basisklasse initialisiert.
    Dies ist ein weiteres Beispiel:

    open class Person(age: Int, name: String) {
        // some code
    }
    class Footballer(age: Int, name: String, club: String): Person(age, name) {
        init {
            println("Der Fußballspieler mit dem Alter $age und dem Namen $name spielt für den Verein $club.")
        }
        fun playFootball() {
            println("Ich spiele Fußball.")
        }
    }
    fun main(args: Array<String>) {
        val f1 = Footballer(29, "Cristiano", "LA Galaxy")
    }

      In diesem Fall hat der Hauptkonstruktor der Ableitungsklasse3Parameter, während die Basisklasse2Parameter. Beachten Sie, dass beide Parameter der Basisklasse bereits initialisiert sind.

  • Wenn es keinen Hauptkonstruktor gibt, muss jede Basisklasse initialisiert werden (durch den Verwendung des Schlüsselworts super), oder es wird an einen anderen Konstruktor delegiert, der diese Operation ausführt. Zum Beispiel

    fun main(args: Array<String>) {
        val p1 = AuthLog("Bad Password")
    }
    open class Log {
        var data: String = ""
        var numberOfData = 0
        constructor(_data: String) {
        }
        constructor(_data: String, _numberOfData: Int) {
            data = _data
            numberOfData = _numberOfData
            println("$data: $numberOfData times")
        }
    }
    class AuthLog: Log {
        constructor(_data: String): this("From AuthLog -> + $_data", 10) {
        }
        constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) {
        }
    }

      Um mehr über die Funktionsweise dieses Programms zu erfahren, besuchen SieKotlin-Nachkonstruktor.

Überladene Mitgliedsfunktion und Eigenschaft

Wenn die Basisklasse und die Ableitungsklasse Mitgliedsfunktionen (oder Eigenschaften) mit dem gleichen Namen enthalten, kann es erforderlich sein, das Schlüsselwort override zu verwenden, um die Mitgliedsfunktion der Ableitungsklasse zu überschreiben, und die Mitgliedsfunktion der Basisklasse mit dem Schlüsselwort open zu verwenden.

Beispiel: Überladene Mitgliedsfunktion

// Leere Hauptkonstruktor
open class Person() {
    open fun displayAge(age: Int) {
        println("meine Alter ist $age.")
    }
}
class Girl: Person() {
    override fun displayAge(age: Int) {}}
        println("Meine virtuelle Alter ist ${age - 5}.")
    }
}
fun main(args: Array<String>) {
    val girl = Girl()
    girl.displayAge(31)
}

Wenn das Programm ausgeführt wird, wird die Ausgabe sein:

die virtuelle Alter ist 26.

Hier girl.displayAge(31) Das displayAge()-Verfahren der Ableitungsklasse Girl aufrufen.

Sie können die Basisklassenattribute auf ähnliche Weise überschreiben.

Bevor Sie die folgenden Beispiele lernen, können Sie Kotlin getter und setter Sehen Sie sich das Funktionieren an.

//Leere Hauptkonstruktor
open class Person() {
    open var age: Int = 0
        get() = field
        set(value) {
            field = value
        }
}
class Girl: Person() {
    override var age: Int = 0
        get() = field
        set(value) {
            field = value - 5
        }
}
fun main(args: Array<String>) {
    val girl = Girl()
    girl.age = 31
    println("meine virtuelle Alter ist ${girl.age}.")
}

Wenn das Programm ausgeführt wird, wird die Ausgabe sein:

Meine virtuelle Alter ist 26.

Wie Sie sehen können, haben wir die Schlüsselwörter override und open sowohl für das Attribut age in der Ableitungsklasse als auch in der Basisklasse verwendet.

Basisklassenmitglieder aufrufen von Ableitungsklassen

Sie können den Schlüsselwort super verwenden, um die Funktionen der Basisklasse aus der Ableitungsklasse aufzurufen (und auf Eigenschaften zuzugreifen). Hier ist, wie man das macht:

open class Person() {
    open fun displayAge(age: Int) {
        println("meine tatsächliche Alter ist $age.")
    }
}
class Girl: Person() {
    override fun displayAge(age: Int) {}}
        //Aufruf der Funktion der Basisklasse
        super.displayAge(age)
        
        println("Meine virtuelle Alter ist ${age - 5}.")
    }
}
fun main(args: Array<String>) {
    val girl = Girl()
    girl.displayAge(31)
}

Wenn das Programm ausgeführt wird, wird die Ausgabe sein:

Meine tatsächliche Alter ist 31.
Meine virtuelle Alter ist 26.