Kotlin Inheritance (met voorbeelden)

In dit artikel leer je over overerving. Meer specifiek, wat is overerving en hoe het in Kotlin te implementeren (met behulp van voorbeelden).

Overerving is een van de belangrijkste kenmerken van objectgeoriënteerd programmeren. Hiermee kan de gebruiker een nieuwe klasse (afgeleide klasse) maken van een bestaande klasse (basisklasse).

De afgeleide klasse erft alle kenmerken van de basisklasse en kan zelf aanvullende kenmerken hebben.

Voordat we ingaan op de details over de overerving van Kotlin, raden we u aan deze twee artikelen te lezen:

  • Kotlin-klasse en objecten
  • Kotlin primaire constructeur

Waarom overerving?

Stel dat u in uw aanvraag drie karakters wilt: een wiskundeleraar , een voetballer en een zakenman .

Omdat alle personages personen zijn, kunnen ze lopen en praten. Ze hebben echter ook een aantal speciale vaardigheden. Een wiskundeleraar kan wiskunde geven , een voetballer kan voetballen en een zakenman kan een bedrijf runnen .

U kunt individueel drie klassen creëren die kunnen lopen, praten en hun speciale vaardigheid kunnen uitvoeren.

In elk van de lessen zou je voor elk personage dezelfde code voor lopen en praten kopiëren.

Als je een nieuwe functie wilt toevoegen - eat, moet je voor elk teken dezelfde code implementeren. Dit kan gemakkelijk foutgevoelig worden (bij het kopiëren) en dubbele codes.

Het zou een stuk gemakkelijker zijn als we een Personklas hadden met basisfuncties zoals praten, lopen, eten, slapen en speciale vaardigheden toevoegen aan die functies volgens onze personages. Dit gebeurt met overerving.

Met behulp van de erfenis, nu heb je niet dezelfde code te implementeren walk(), talk()en eat()voor elke klasse. Je moet ze gewoon erven .

Dus voor MathTeacher(afgeleide klasse), erft u alle kenmerken van een Person(basisklasse) en voegt u een nieuwe functie toe teachMath(). Evenzo ervaar je voor de Footballerklas alle kenmerken van de Personklas en voeg je een nieuwe functie toe playFootball(), enzovoort.

Dit maakt uw code schoner, begrijpelijker en uitbreidbaar.

Het is belangrijk om te onthouden: wanneer u met overerving werkt, moet elke afgeleide klasse voldoen aan de voorwaarde of het "een" basisklasse is of niet. In het bovenstaande voorbeeld MathTeacher is a Person , Footballer is a Person . Je kunt zoiets niet hebben als, Businessman is een Business .

Kotlin erfenis

Laten we proberen de bovenstaande discussie in code te implementeren:

 open klas Persoon (leeftijd: Int) (// code voor eten, praten, lopen) klas Math Leraar (leeftijd: Int): Persoon (leeftijd) (// andere kenmerken van wiskundeleraar) klas Voetballer (leeftijd: Int): Persoon ( leeftijd) (// andere kenmerken van voetballer) klasse Zakenman (leeftijd: Int): Persoon (leeftijd) (// andere kenmerken van zakenman)

Hier, Personis een basisklasse, en klassen MathTeacher, Footballeren Businessmanzijn afgeleid van de klasse persoon.

Let op, het sleutelwoord openvoor de basisklasse Person. Het is belangrijk.

De lessen in Kotlin zijn standaard definitief. Als u bekend bent met Java, weet u dat een laatste klasse niet kan worden onderverdeeld. Door de open annotatie op een klasse te gebruiken, kunt u met de compiler er nieuwe klassen uit afleiden.

Voorbeeld: Kotlin Inheritance

 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() )

Wanneer u het programma uitvoert, is de uitvoer:

Mijn naam is Jack. Mijn leeftijd is 25. Ik geef les op de basisschool. Mijn naam is Cristiano. Mijn leeftijd is 29. Ik speel voor LA Galaxy.

Hier twee klassen MathTeacheren Footballerzijn afgeleid van de Personklasse.

De primaire constructor van de Personklasse heeft twee eigenschappen gedeclareerd: leeftijd en naam, en het heeft een initialisatieblok. Het startblok (en lidfuncties) van de basisklasse Personis toegankelijk voor de objecten van afgeleide klassen ( MathTeacheren Footballer).

Afgeleide klassen MathTeacheren Footballerhebben hun eigen lidfuncties teachMaths()en playFootball()respectievelijk. Deze functies zijn alleen toegankelijk vanuit de objecten van hun respectievelijke klasse.

Wanneer het object t1 van MathTeacherklasse is gemaakt,

 val t1 = MathTeacher (25; "Jack")

De parameters worden doorgegeven aan de primaire constructor. In Kotlin wordt initblok aangeroepen wanneer het object wordt gemaakt. Omdat, MathTeacheris afgeleid van Personclass, zoekt het naar initialisatieblok in de basisklasse (Person) en voert het uit. Als het MathTeacherinit-blok had, zou de compiler ook het init-blok van de afgeleide klasse hebben uitgevoerd.

Vervolgens wordt de teachMaths()functie voor object t1aangeroepen met behulp van t1.teachMaths()statement.

Het programma werkt op dezelfde manier als object f1van de Footballerklasse wordt gemaakt. Het voert het init-blok van de basisklasse uit. Vervolgens wordt de class- playFootball()methode Footballeraangeroepen met statement f1.playFootball().

Belangrijke opmerkingen: Kotlin Inheritance

  • Als de klasse een primaire constructor heeft, moet de basis worden geïnitialiseerd met de parameters van de primaire constructor. In het bovenstaande programma hebben beide afgeleide klassen twee parameters ageen name, en beide parameters worden geïnitialiseerd in de primaire constructor in de basisklasse.
    Hier is nog een voorbeeld:
     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 heeft de primaire constructor van de afgeleide klasse 3 parameters en heeft de basisklasse 2 parameters. Merk op dat beide parameters van de basisklasse worden geïnitialiseerd.
  • In het geval dat er geen primaire constructor is, moet elke basisklasse de basis initialiseren (met behulp van het super-sleutelwoord) of delegeren aan een andere constructor die dat doet. Bijvoorbeeld,
     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) ( ) )
    Bezoek Kotlin Secondary Constructor voor meer informatie over hoe dit programma werkt.

Functies en eigenschappen van leden overschrijven

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

U kunt functies (en toegangseigenschappen) van de basisklasse aanroepen vanuit een afgeleide klasse met behulp van supertrefwoord. Hier is hoe:

 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) )

Wanneer u het programma uitvoert, is de uitvoer:

 Mijn leeftijd is 31. Mijn nepleeftijd is 26.

Interessante artikelen...