Tässä artikkelissa opit perinnöstä. Tarkemmin sanottuna mikä on perintö ja miten se toteutetaan Kotlinissa (esimerkkien avulla).
Perintö on yksi olio-ohjelmoinnin pääpiirteistä. Sen avulla käyttäjä voi luoda uuden luokan (johdettu luokka) olemassa olevasta luokasta (perusluokka).
Johdettu luokka perii kaikki ominaisuudet perusluokalta, ja sillä voi olla omia lisäominaisuuksia.
Ennen kuin tutustut Kotlinin perintöön, suosittelemme tarkistamaan nämä kaksi artikkelia:
- Kotlin-luokka ja esineet
- Kotlinin ensisijainen rakentaja
Miksi perintö?
Oletetaan, että hakemuksessasi haluat kolme merkkiä - matematiikan opettaja , jalkapalloilija ja liikemies .
Koska kaikki hahmot ovat henkilöitä, he voivat kävellä ja puhua. Heillä on kuitenkin myös joitain erityisiä taitoja. Matematiikan opettaja voi opettaa matematiikkaa , jalkapalloilija voi pelata jalkapalloa ja liikemies voi johtaa yritystä .
Voit luoda erikseen kolme luokkaa, jotka voivat kävellä, puhua ja suorittaa erityisosaamistaan.
Kussakin luokassa kopioit saman koodin kävelyä ja puhetta varten jokaiselle merkille.
Jos haluat lisätä uuden ominaisuuden - syö, sinun on otettava käyttöön sama koodi jokaiselle merkille. Tästä voi tulla helposti virhealtista (kopioitaessa) ja päällekkäisiä koodeja.
Olisi paljon helpompaa, jos meillä olisi Person
luokka, jolla on perusominaisuudet, kuten puhuminen, kävely, syöminen, nukkuminen ja erityisosaamisen lisääminen näihin ominaisuuksiin hahmojemme mukaan. Tämä tapahtuu perinnöllä.
Käyttämällä perintö, nyt et toteuttaa samaa tunnusta walk()
, talk()
ja eat()
kullekin luokalle. Sinun tarvitsee vain periä ne.
Joten MathTeacher
(johdettu luokka) perit kaikki Person
(perusluokan) ominaisuudet ja lisäät uuden ominaisuuden teachMath()
. Samoin Footballer
luokassa perit kaikki Person
luokan ominaisuudet ja lisäät uuden ominaisuuden playFootball()
ja niin edelleen.
Tämä tekee koodistasi puhtaamman, ymmärrettävämmän ja laajennettavissa olevan.
On tärkeää muistaa: Kun työskentelet perinnön kanssa, jokaisen johdetun luokan on täytettävä ehto, onko se " perus " luokka vai ei. Yllä olevassa esimerkissä MathTeacher
on a Person
, Footballer
on a Person
. Sinulla ei voi olla jotain sellaista, Businessman
on a Business
.
Kotlinin perintö
Yritetään toteuttaa yllä oleva keskustelu koodina:
avoin luokka Henkilö (ikä: Int) (// syömisen, puhumisen, kävelyn koodi) luokka MathTeacher (ikä: Int): Henkilö (ikä) (// matematiikan opettajan muut ominaisuudet) luokka Jalkapalloilija (ikä: Int): Henkilö ( ikä) (// muut jalkapalloilijan piirteet) luokka Liikemies (ikä: Int): Henkilö (ikä) (// liikemiehen muut ominaisuudet)
Täällä Person
on perustaa luokan, ja luokat MathTeacher
, Footballer
ja Businessman
ovat peräisin Person luokan.
Ilmoitusta, avainsanan open
ennen perustaa luokan, Person
. Se on tärkeää.
Oletuksena Kotlinin luokat ovat lopullisia. Jos olet perehtynyt Java-ohjelmaan, tiedät, että lopullista luokkaa ei voida luokitella aliluokkaan. Käyttämällä avointa merkintää luokassa, kääntäjä antaa sinulle mahdollisuuden johtaa siitä uusia luokkia.
Esimerkki: Kotlinin perintö
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() )
Kun suoritat ohjelmaa, tulos on:
Minun nimeni on Jack. Ikäni on 25, opetan peruskoulussa. Nimeni on Cristiano. Ikäni on 29, pelaan LA Galaxy -sarjassa.
Tässä kaksi luokkaa MathTeacher
ja Footballer
ovat peräisin Person
luokasta.
Person
Luokan ensisijainen rakentaja ilmoitti kaksi ominaisuutta: ikä ja nimi, ja sillä on alustuslohko. Perusluokan initiaattorilohkoon (ja jäsenfunktioihin) Person
pääsee johdettujen luokkien ( MathTeacher
ja Footballer
) objekteilla .
Johdetut luokat MathTeacher
ja Footballer
niillä on omat jäsenfunktiot teachMaths()
ja playFootball()
vastaavasti. Nämä toiminnot ovat käytettävissä vain niiden luokan esineistä.
Kun MathTeacher
luokan t1 luodaan,
val t1 = MathTeacher (25, "Jack")
Parametrit välitetään päärakentajalle. Kotlinissa init
estoa kutsutaan, kun objekti luodaan. Koska MathTeacher
on johdettu Person
luokasta, se etsii alustuslohkon perusluokasta (Henkilö) ja suorittaa sen. Jos MathTeacher
init-lohko olisi ollut, kääntäjä olisi suorittanut myös johdetun luokan init-lohkon.
Seuraavaksi teachMaths()
objektin funktiota t1
kutsutaan t1.teachMaths()
lauseella.
Ohjelma toimii samalla kun kohteena f1
on Footballer
luokan luodaan. Se suorittaa perusluokan init-lohkon. Sitten luokan playFootball()
menetelmää Footballer
kutsutaan lauseella f1.playFootball()
.
Tärkeitä huomautuksia: Kotlinin perintö
- Jos luokassa on ensisijainen konstruktori, pohja on alustettava ensisijaisen rakentajan parametreilla. Edellä mainitussa ohjelmassa molemmilla johdetuilla luokilla on kaksi parametria
age
janame
, ja molemmat näistä parametreista alustetaan perusluokan perusrakentajalla.
Tässä on toinen esimerkki: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") )
- Jos ensisijaista konstruktoria ei ole, jokaisen perusluokan on alustettava tukiasema (superavainsanaa käyttäen) tai delegoitava toiselle rakentajalle, joka tekee sen. Esimerkiksi,
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) ( ) )
Jäsenten toiminnot ja ominaisuudet
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
Voit kutsua perusluokan funktioita (ja käyttöominaisuuksia) johdetusta luokasta käyttämällä super
avainsanaa. Näin:
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) )
Kun suoritat ohjelmaa, tulos on:
Ikäni on 31. Minun väärennetty ikäni on 26.