V tem članku boste izvedeli več o dedovanju. Natančneje, kaj je dedovanje in kako ga uporabiti v Kotlinu (s pomočjo primerov).
Dedovanje je ena ključnih značilnosti objektno usmerjenega programiranja. Uporabniku omogoča, da iz obstoječega razreda (osnovni razred) ustvari nov razred (izpeljani razred).
Izpeljani razred podeduje vse funkcije osnovnega razreda in ima lahko lastne dodatne funkcije.
Preden se podrobno seznanimo z dedovanjem Kotlina, vam priporočamo, da preverite ta dva članka:
- Kotlinov razred in predmeti
- Kotlinov primarni konstruktor
Zakaj dedovanje?
Recimo, da v svoji prijavi želite tri znake - učitelja matematike , nogometaša in poslovneža .
Ker so vsi liki osebe, lahko hodijo in govorijo. Imajo pa tudi nekaj posebnih veščin. Učitelj matematike lahko poučuje matematiko , nogometaš lahko igra nogomet in poslovnež lahko vodi podjetje .
Posamezno lahko ustvarite tri razrede, ki lahko hodijo, govorijo in izvajajo svoje posebne spretnosti.
V vsakem od predavanj bi kopirali isto kodo za sprehod in pogovor za vsak lik.
Če želite dodati novo funkcijo - jejte, morate za vsak znak uporabiti isto kodo. To lahko zlahka postane podvrženo napakam (pri kopiranju) in podvojenih kod.
Veliko lažje bi bilo, če bi imeli Person
razred z osnovnimi lastnostmi, kot so pogovor, hoja, prehranjevanje, spanje in dodajanje posebnih veščin tem značilnostim po naših likih. To se naredi z dedovanjem.
Z dediščino, zdaj pa ne izvajajo isto kodo za walk()
, talk()
in eat()
za vsak razred. Samo podedovati jih morate .
Torej za MathTeacher
(izpeljani razred) podedujete vse funkcije Person
(osnovnega razreda) in dodate novo funkcijo teachMath()
. Prav tako za Footballer
razred podedujete vse funkcije Person
razreda, dodate novo funkcijo playFootball()
itd.
Zaradi tega je vaša koda čistejša, razumljiva in razširljiva.
Pomembno si je zapomniti: Pri delu z dedovanjem mora vsak izpeljani razred izpolnjevati pogoj, ali je " osnovni razred" ali ne. V zgornjem primeru MathTeacher
je a Person
, Footballer
je a Person
. Ne morete imeti česa takega, Businessman
je a Business
.
Dediščina Kotlin
Poskusimo zgornjo razpravo implementirati v kodo:
odprti razred Oseba (starost: Int) (// koda za prehranjevanje, govorjenje, hojo) razred MathTeacher (starost: Int): Oseba (starost) (// druge značilnosti učitelja matematike) razred Nogometaš (starost: Int): Oseba ( starost) (// druge značilnosti nogometaša) razred Poslovec (starost: Int): Oseba (starost) (// druge značilnosti poslovneža)
Tu Person
je osnova razred in razredi MathTeacher
, Footballer
in Businessman
so pridobljeni iz razreda Oseba.
Obvestilo, ključna beseda open
pred osnovnega razreda, Person
. Pomembno je.
Privzeto so razredi v Kotlinu dokončni. Če poznate Javo, veste, da končnega razreda ni mogoče podrazvrstiti. Z uporabo odprtega zapisa v razredu vam prevajalnik omogoča, da iz njega izpeljete nove razrede.
Primer: Kotlin Dedovanje
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() )
Ko zaženete program, bo rezultat:
Moje ime je Jack. Moja starost je 25 let, poučujem v osnovni šoli. Moje ime je Cristiano. Moja starost je 29 let, igram za LA Galaxy.
Tu sta dva razreda MathTeacher
in Footballer
izhajata iz Person
razreda.
Primarni konstruktor Person
razreda je razglasil dve lastnosti: starost in ime in ima blok inicializatorja. Person
Predmeti izvedenih razredov ( MathTeacher
in Footballer
) lahko dostopajo do bloka pobudnika (in funkcij člana) osnovnega razreda .
Izpeljana razrede MathTeacher
in Footballer
imajo svoje funkcije države teachMaths()
in playFootball()
v tem zaporedju. Te funkcije so dostopne samo iz predmetov njihovega razreda.
Ko MathTeacher
se ustvari objekt razreda t1 ,
val t1 = MathTeacher (25, "Jack")
Parametri se posredujejo primarnemu konstruktorju. V Kotlinu se init
blok pokliče, ko je objekt ustvarjen. Ker MathTeacher
je izpeljan iz Person
razreda, išče blok inicializatorja v osnovnem razredu (oseba) in ga izvrši. Če bi MathTeacher
imel blok init, bi prevajalnik izvedel tudi blok init izpeljanega razreda.
Nato se teachMaths()
funkcija stavka t1
pokliče z uporabo t1.teachMaths()
stavka.
Program deluje podobno, ko objekt f1
za Footballer
se ustvari razred. Izvede blok init osnovnega razreda. Nato se playFootball()
metoda Footballer
razreda pokliče z uporabo stavka f1.playFootball()
.
Pomembne opombe: Kotlin Inheritance
- Če ima razred primarni konstruktor, je treba osnovo inicializirati s parametri primarnega konstruktorja. V zgornjem programu imata oba izvedena razreda dva parametra
age
inname
in oba parametra sta inicializirana v primarnem konstruktorju v osnovnem razredu.
Tu je še en primer: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") )
- V primeru, da ni primarnega konstruktorja, mora vsak osnovni razred inicializirati bazo (z uporabo ključne besede super) ali jo prenesti na drug konstruktor, ki to stori. Na primer
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) ( ) )
Preglasitev funkcij in lastnosti članov
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
Funkcije (in lastnosti dostopa) osnovnega razreda lahko prikličete iz izvedenega razreda z uporabo super
ključne besede. Takole:
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) )
Ko zaženete program, bo rezultat:
Moja starost je 31. Moja ponarejena starost je 26 let.