I den här artikeln lär du dig om arv. Mer specifikt, vad är arv och hur man implementerar det i Kotlin (med hjälp av exempel).
Arv är en av de viktigaste funktionerna i objektorienterad programmering. Det tillåter användare att skapa en ny klass (härledd klass) från en befintlig klass (basklass).
Den härledda klassen ärver alla funktioner från basklassen och kan ha ytterligare funktioner.
Innan du går in på detaljer om Kotlin-arv rekommenderar vi att du kontrollerar dessa två artiklar:
- Kotlin klass och objekt
- Kotlin Primärkonstruktör
Varför arv?
Anta att du i din ansökan vill ha tre karaktärer - en matematiklärare , en fotbollsspelare och en affärsman .
Eftersom alla karaktärer är personer kan de gå och prata. Men de har också några speciella färdigheter. En matematiklärare kan undervisa matematik , en fotbollsspelare kan spela fotboll och en affärsman kan driva ett företag .
Du kan individuellt skapa tre klasser som kan gå, prata och utföra sin speciella skicklighet.
I varje klass skulle du kopiera samma kod för att gå och prata för varje karaktär.
Om du vill lägga till en ny funktion - äta, måste du implementera samma kod för varje tecken. Detta kan lätt bli felbenägen (vid kopiering) och duplicera koder.
Det skulle vara mycket lättare om vi hade en Person
klass med grundläggande funktioner som att prata, gå, äta, sova och lägga till speciella färdigheter till dessa funktioner enligt våra karaktärer. Detta görs med arv.
Med hjälp av arv, nu behöver du inte implementera samma kod för walk()
, talk()
och eat()
för varje klass. Du behöver bara ärva dem.
Så för MathTeacher
(härledd klass) ärver du alla funktioner i en Person
(basklass) och lägger till en ny funktion teachMath()
. På samma sätt Footballer
ärver du alla Person
klassens funktioner för klassen och lägger till en ny funktion playFootball()
och så vidare.
Detta gör din kod renare, förståelig och utdragbar.
Det är viktigt att komma ihåg: När du arbetar med arv bör varje härledd klass uppfylla villkoret om det "är" en basklass eller inte. I exemplet ovan MathTeacher
är a Person
, Footballer
är a Person
. Du kan inte ha något liknande, Businessman
är en Business
.
Kotlins arv
Låt oss försöka implementera ovanstående diskussion i kod:
öppen klass Person (ålder: Int) (// kod för att äta, prata, gå) klass MathTeacher (ålder: Int): Person (ålder) (// andra funktioner i matematiklärare) klass Fotbollsspelare (ålder: Int): Person ( ålder) (// andra funktioner i fotbollsspelare) klass Affärsman (ålder: Int): Person (ålder) (// andra funktioner i affärsmannen)
Här, Person
är en basklass och klasser MathTeacher
, Footballer
och Businessman
är härledda från den person klassen.
Lägg märke till nyckelordet open
innan basklass, Person
. Det är viktigt.
Som standard är klasser i Kotlin slutgiltiga. Om du känner till Java vet du att en slutklass inte kan delklassas. Genom att använda den öppna anteckningen på en klass tillåter kompilatorn att härleda nya klasser från den.
Exempel: 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() )
När du kör programmet blir resultatet:
Mitt namn är Jack. Min ålder är 25 år jag undervisar i grundskolan. Jag heter Cristiano. Min ålder är 29 Jag spelar för LA Galaxy.
Här är två klasser MathTeacher
och Footballer
härledda från Person
klassen.
Den primära konstruktören i Person
klassen förklarade två egenskaper: ålder och namn, och den har ett initialiseringsblock. Initialiseringsblocket (och medlemsfunktionerna) för basklassen Person
kan nås av objekten för härledda klasser ( MathTeacher
och Footballer
).
Härledda klasser MathTeacher
och Footballer
har egna medlemsfunktioner teachMaths()
och playFootball()
respektive. Dessa funktioner är endast tillgängliga från objekten i deras respektive klass.
När objektet t1 för MathTeacher
klass skapas,
val t1 = MathTeacher (25, "Jack")
Parametrarna skickas till den primära konstruktorn. I Kotlin init
anropas block när objektet skapas. Eftersom, MathTeacher
härleds från Person
klass, letar det efter initialiseringsblock i basklassen (Person) och kör det. Om det MathTeacher
hade init-blocket skulle kompilatorn också ha kört init-blocket för den härledda klassen.
Därefter kallas teachMaths()
funktionen för objekt med t1
hjälp av t1.teachMaths()
uttalande.
Programmet fungerar på samma sätt när föremål f1
av Footballer
klass skapas. Det kör init-blocket för basklassen. Sedan playFootball()
metoden Footballer
är klass som kallas använder uttalande f1.playFootball()
.
Viktiga anmärkningar: Kotlin Inheritance
- Om klassen har en primär konstruktör måste basen initieras med parametrarna för den primära konstruktören. I ovanstående program, båda härledda klasser har två parametrar
age
ochname
, och båda dessa parametrar initialiseras i primär konstruktor i basklassen.
Här är ett annat exempel: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") )
- Om det inte finns någon primär konstruktör måste varje basklass initiera basen (med hjälp av supernyckelord) eller delegera till en annan konstruktör som gör det. Till exempel,
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) ( ) )
Åsidosättande av medlemsfunktioner och egenskaper
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
Du kan anropa funktioner (och komma åt egenskaper) för basklassen från en härledd klass med hjälp av super
nyckelord. Här är hur:
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) )
När du kör programmet blir resultatet:
Min ålder är 31. Min falska ålder är 26.