Kotlin-Vererbung (mit Beispielen)

In diesem Artikel erfahren Sie mehr über Vererbung. Genauer gesagt, was ist Vererbung und wie wird sie in Kotlin implementiert (anhand von Beispielen)?

Vererbung ist eines der Hauptmerkmale der objektorientierten Programmierung. Es ermöglicht dem Benutzer, eine neue Klasse (abgeleitete Klasse) aus einer vorhandenen Klasse (Basisklasse) zu erstellen.

Die abgeleitete Klasse erbt alle Features von der Basisklasse und kann zusätzliche eigene Features haben.

Bevor Sie auf Details zur Kotlin-Vererbung eingehen, empfehlen wir Ihnen, diese beiden Artikel zu lesen:

  • Kotlin Klasse und Objekte
  • Kotlin Primärkonstruktor

Warum Vererbung?

Angenommen, Sie möchten in Ihrer Bewerbung drei Charaktere - einen Mathematiklehrer , einen Fußballspieler und einen Geschäftsmann .

Da alle Charaktere Personen sind, können sie gehen und sprechen. Sie haben jedoch auch einige besondere Fähigkeiten. Ein Mathematiklehrer kann Mathematik unterrichten , ein Fußballspieler kann Fußball spielen und ein Geschäftsmann kann ein Geschäft führen .

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

In jeder der Klassen würden Sie für jedes Zeichen denselben Code für Gehen und Sprechen kopieren.

Wenn Sie eine neue Funktion hinzufügen möchten, müssen Sie für jedes Zeichen denselben Code implementieren. Dies kann leicht fehleranfällig werden (beim Kopieren) und doppelte Codes.

Es wäre viel einfacher, wenn wir eine PersonKlasse mit grundlegenden Funktionen wie Sprechen, Gehen, Essen, Schlafen hätten und diesen Funktionen gemäß unseren Charakteren besondere Fähigkeiten hinzufügen würden. Dies erfolgt durch Vererbung.

Vererbung, jetzt implementieren Sie nicht den gleichen Code für walk(), talk()und eat()für jede Klasse. Sie müssen sie nur erben .

Für MathTeacher(abgeleitete Klasse) erben Sie also alle Features einer Person(Basisklasse) und fügen ein neues Feature hinzu teachMath(). Ebenso Footballererben Sie für die Klasse alle Funktionen der PersonKlasse und fügen eine neue Funktion hinzu playFootball()und so weiter.

Dies macht Ihren Code sauberer, verständlicher und erweiterbarer.

Es ist wichtig, sich daran zu erinnern: Wenn Sie mit Vererbung arbeiten, sollte jede abgeleitete Klasse die Bedingung erfüllen, ob es sich um eine Basisklasse handelt oder nicht. Im obigen Beispiel MathTeacher ist a Person , Footballer ist a Person . Sie können so etwas nicht haben, Businessman ist ein Business .

Kotlin-Vererbung

Versuchen wir, die obige Diskussion im Code zu implementieren:

 offene Klasse Person (Alter: Int) (// Code zum Essen, Sprechen, Gehen) Klasse MathTeacher (Alter: Int): Person (Alter) (// andere Merkmale des Mathematiklehrers) Klasse Footballer (Alter: Int): Person ( Alter) (// andere Merkmale des Fußballspielers) Klasse Geschäftsmann (Alter: Int): Person (Alter) (// andere Merkmale des Geschäftsmanns)

Hier Personist eine Basisklasse und Klassen MathTeacher, Footballerund Businessmansind von der Person - Klasse abgeleitet.

Beachten Sie, das Schlüsselwort openvor der Basisklasse Person. Es ist wichtig.

Standardmäßig sind Klassen in Kotlin endgültig. Wenn Sie mit Java vertraut sind, wissen Sie, dass eine endgültige Klasse nicht in Unterklassen unterteilt werden kann. Durch die Verwendung der offenen Annotation für eine Klasse können Sie mit dem Compiler neue Klassen daraus ableiten.

Beispiel: Kotlin-Vererbung

 open class Person(age: Int, name: String) ( init ( println("My name is $name.") println("My age is $age") ) ) class MathTeacher(age: Int, name: String): Person(age, name) ( fun teachMaths() ( println("I teach in primary school.") ) ) class Footballer(age: Int, name: String): Person(age, name) ( fun playFootball() ( println("I play for LA Galaxy.") ) ) fun main(args: Array) ( val t1 = MathTeacher(25, "Jack") t1.teachMaths() println() val f1 = Footballer(29, "Christiano") f1.playFootball() )

Wenn Sie das Programm ausführen, lautet die Ausgabe wie folgt:

Ich heiße Jack. Ich bin 25 Jahre alt und unterrichte in der Grundschule. Ich heiße Cristiano. Ich bin 29 Jahre alt und spiele für LA Galaxy.

Hier zwei Klassen MathTeacherund Footballerwerden von der PersonKlasse abgeleitet.

Der primäre Konstruktor der PersonKlasse deklarierte zwei Eigenschaften: Alter und Name und verfügt über einen Initialisierungsblock. Auf den Initilizer-Block (und die Elementfunktionen) der Basisklasse Personkönnen die Objekte abgeleiteter Klassen ( MathTeacherund Footballer) zugreifen .

Abgeleitete Klassen MathTeacherund Footballerhaben ihre eigenen Mitgliedsfunktionen teachMaths()und playFootball()jeweils. Auf diese Funktionen kann nur von den Objekten der jeweiligen Klasse aus zugegriffen werden.

Wenn das Objekt t1 der MathTeacherKlasse erstellt wird,

 val t1 = MathTeacher (25, "Jack")

Die Parameter werden an den primären Konstruktor übergeben. In Kotlin wird der initBlock beim Erstellen des Objekts aufgerufen. Da MathTeacheres von der PersonKlasse abgeleitet ist , sucht es in der Basisklasse (Person) nach dem Initialisierungsblock und führt ihn aus. Wenn der MathTeacherInit-Block hätte, hätte der Compiler auch den Init-Block der abgeleiteten Klasse ausgeführt.

Als nächstes wird die teachMaths()Funktion für das Objekt t1mit der t1.teachMaths()Anweisung aufgerufen .

Das Programm funktioniert auf ähnliche Weise , wenn das Objekt f1der FootballerKlasse erstellt wird. Es führt den Init-Block der Basisklasse aus. Dann wird die playFootball()Methode der FootballerKlasse using-Anweisung aufgerufen f1.playFootball().

Wichtige Hinweise: Kotlin-Vererbung

  • Wenn die Klasse einen Primärkonstruktor hat, muss die Basis mit den Parametern des Primärkonstruktors initialisiert werden. Im obigen Programm haben beide abgeleiteten Klassen zwei Parameter ageund name, und beide Parameter werden im Primärkonstruktor in der Basisklasse initialisiert.
    Hier 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("Football player $name of age $age and plays for $club.") ) fun playFootball() ( println("I am playing football.") ) ) fun main(args: Array) ( val f1 = Footballer(29, "Cristiano", "LA Galaxy") )  
    Hier hat der primäre Konstruktor der abgeleiteten Klasse 3 Parameter und die Basisklasse 2 Parameter. Beachten Sie, dass beide Parameter der Basisklasse initialisiert werden.
  • Wenn kein primärer Konstruktor vorhanden ist, muss jede Basisklasse die Basis initialisieren (mit dem Schlüsselwort super) oder an einen anderen Konstruktor delegieren, der dies tut. Beispielsweise,
     fun main(args: Array) ( 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 Sie Kotlin Secondary Constructor.

Überschreiben von Elementfunktionen und -eigenschaften

If the base class and the derived class contains a member function (or property) with the same name, you can need to override the member function of the derived class using override keyword, and use open keyword for the member function of the base class.

Example: Overriding Member Function

 // Empty primary constructor open class Person() ( open fun displayAge(age: Int) ( println("My age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

When you run the program, the output will be:

 My fake age is 26.

Here, girl.displayAge(31) calls the displayAge() method of the derived class Girl.

You can override property of the base class in similar way.

Visit how Kotlin getters and setters work in Kotlin before you check the example below.

 // Empty primary constructor 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) ( val girl = Girl() girl.age = 31 println("My fake age is $(girl.age).") )

When you run the program, the output will be:

 My fake age is 26.

As you can see, we have used override and open keywords for age property in derived class and base class respectively.

Calling Members of Base Class from Derived Class

Sie können Funktionen (und Zugriffseigenschaften) der Basisklasse von einer abgeleiteten Klasse mit dem superSchlüsselwort aufrufen . Hier ist wie:

 open class Person() ( open fun displayAge(age: Int) ( println("My actual age is $age.") ) ) class Girl: Person() ( override fun displayAge(age: Int) ( // calling function of base class super.displayAge(age) println("My fake age is $(age - 5).") ) ) fun main(args: Array) ( val girl = Girl() girl.displayAge(31) )

Wenn Sie das Programm ausführen, lautet die Ausgabe wie folgt:

 Mein Alter ist 31. Mein falsches Alter ist 26.

Interessante Beiträge...