I denne artikkelen vil du lære om arv. Mer spesifikt, hva er arv og hvordan man implementerer det i Kotlin (ved hjelp av eksempler).
Arv er en av nøkkelfunksjonene i objektorientert programmering. Det lar brukeren opprette en ny klasse (avledet klasse) fra en eksisterende klasse (basisklasse).
Den avledede klassen arver alle funksjonene fra basisklassen og kan ha egne funksjoner.
Før du går inn i detaljer om Kotlin-arv, anbefaler vi deg å sjekke disse to artiklene:
- Kotlin klasse og gjenstander
- Kotlin Primærkonstruktør
Hvorfor arv?
Anta at du i søknaden din vil ha tre tegn - en matematikklærer , en fotballspiller og en forretningsmann .
Siden alle karakterene er personer, kan de gå og snakke. Imidlertid har de også noen spesielle ferdigheter. En matematikklærer kan undervise i matematikk , en fotballspiller kan spille fotball og en forretningsmann kan drive virksomhet .
Du kan opprette tre klasser hver for seg som kan gå, snakke og utføre deres spesielle ferdigheter.
I hver av klassene ville du kopiere den samme koden for å gå og snakke for hver karakter.
Hvis du vil legge til en ny funksjon - spis, må du implementere den samme koden for hvert tegn. Dette kan lett bli feilutsatt (når du kopierer) og duplisere koder.
Det ville være mye lettere hvis vi hadde en Person
klasse med grunnleggende funksjoner som snakk, gå, spise, sove og legge til spesielle ferdigheter til disse funksjonene i henhold til karakterene våre. Dette gjøres ved hjelp av arv.
Ved hjelp av arv, nå trenger du ikke implementere den samme koden for walk()
, talk()
og eat()
for hver klasse. Du trenger bare å arve dem.
Så for MathTeacher
(avledet klasse) arver du alle funksjonene i en Person
(baseklasse) og legger til en ny funksjon teachMath()
. På samme måte, for Footballer
klassen, arver du alle funksjonene i Person
klassen og legger til en ny funksjon playFootball()
og så videre.
Dette gjør koden renere, forståelig og utvidbar.
Det er viktig å huske: Når du arbeider med arv, bør hver avledet klasse tilfredsstille betingelsen om det er "en" basisklasse eller ikke. I eksemplet ovenfor MathTeacher
er a Person
, Footballer
er a Person
. Du kan ikke ha noe sånt, Businessman
er en Business
.
Kotlin-arv
La oss prøve å implementere diskusjonen ovenfor i kode:
åpen klasse Person (alder: Int) (// kode for å spise, snakke, gå) klasse MathTeacher (alder: Int): Person (alder) (// andre funksjoner i matematikklærer) klasse Fotballspiller (alder: Int): Person ( alder) (// andre funksjoner i fotballspiller) klasse Forretningsmann (alder: Int): Person (alder) (// andre funksjoner i forretningsmann)
Her Person
er en base klasse, og klasser MathTeacher
, Footballer
og Businessman
er utledet fra Person-klassen.
Varsel, nøkkelordet open
før base klassen, Person
. Det er viktig.
Som standard er klassene i Kotlin endelige. Hvis du er kjent med Java, vet du at en avsluttende klasse ikke kan underklasseres. Ved å bruke den åpne kommentaren på en klasse, lar kompilatoren deg utlede nye klasser fra den.
Eksempel: Kotlin Arv
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 kjører programmet, vil utdataene være:
Mitt navn er Jack. Min alder er 25 år jeg lærer på barneskolen. Jeg heter Cristiano. Min alder er 29 Jeg spiller for LA Galaxy.
Her er to klasser MathTeacher
og Footballer
er avledet fra Person
klassen.
Den primære konstruktøren i Person
klassen erklærte to egenskaper: alder og navn, og den har en initialiseringsblokk. Initiliseringsblokken (og medlemsfunksjonene) til baseklassen Person
kan nås av objektene til avledede klasser ( MathTeacher
og Footballer
).
Avledede klasser MathTeacher
og Footballer
har sine egne medlemsfunksjoner teachMaths()
og playFootball()
henholdsvis. Disse funksjonene er bare tilgjengelige fra gjenstandene i deres respektive klasse.
Når objektet t1 av MathTeacher
klassen er opprettet,
val t1 = MathTeacher (25, "Jack")
Parametrene overføres til den primære konstruktøren. I Kotlin init
kalles blokk når objektet er opprettet. Siden, MathTeacher
er avledet fra Person
klasse, ser den etter initialiseringsblokk i basisklassen (Person) og utfører den. Hvis den MathTeacher
hadde init-blokken, ville kompilatoren også ha utført init-blokken til den avledede klassen.
Deretter kalles teachMaths()
funksjonen for objektet t1
ved hjelp av t1.teachMaths()
uttalelse.
Programmet fungerer på samme måte når objekt f1
av Footballer
klassen er opprettet. Den utfører initblokken til baseklassen. Deretter playFootball()
metoden Footballer
er klasse kalles bruker uttalelsen f1.playFootball()
.
Viktige merknader: Kotlin Inheritance
- Hvis klassen har en primær konstruktør, må basen initialiseres ved hjelp av parametrene til den primære konstruktøren. I de ovennevnte program, begge avledet klasser har to parametere
age
ogname
, og begge disse parametrene initialiseres i primær konstruktøren i basisklassen.
Her er et annet eksempel: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") )
- I tilfelle ingen primærkonstruktør, må hver baseklasse initialisere basen (ved hjelp av supernøkkelord), eller delegere til en annen konstruktør som gjør det. For eksempel,
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) ( ) )
Overstyrende medlemsfunksjoner og 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 ringe til funksjoner (og få tilgang til egenskaper) til baseklassen fra en avledet klasse ved hjelp av super
nøkkelord. Dette er hvordan:
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 kjører programmet, vil utdataene være:
Min alder er 31. Min falske alder er 26.