Ebben a cikkben megismerheti az öröklést. Pontosabban, mi az öröklés és hogyan kell azt Kotlinban megvalósítani (példák segítségével).
Az öröklés az objektum-orientált programozás egyik legfontosabb jellemzője. Lehetővé teszi a felhasználó számára, hogy új osztályt (származtatott osztályt) hozzon létre egy meglévő osztályból (alaposztály).
A származtatott osztály az összes tulajdonságot örökölte az alaposztálytól, és további sajátosságokkal is rendelkezhet.
Mielőtt a Kotlin-örökség részleteivel foglalkozna, javasoljuk, hogy ellenőrizze ezt a két cikket:
- Kotlin osztály és tárgyak
- Kotlin elsődleges kivitelező
Miért öröklés?
Tegyük fel, hogy az alkalmazásában három karaktert szeretne - matematikatanár , futballista és üzletember .
Mivel az összes karakter személy, járni és beszélgetni tud. Vannak azonban speciális képességeik is. A matek tanár tanít matematikát , egy futballista focizni és üzletember is a vállalkozások működtetésének .
Három osztályt hozhat létre külön-külön, akik tudnak járni, beszélgetni és elvégezni különleges képességeiket.
Az osztályok mindegyikében ugyanazt a kódot másolná az egyes szereplőkhöz.
Ha új funkciót szeretne hozzáadni - enni, akkor minden karakterhez ugyanazt a kódot kell végrehajtania. Ez könnyen hibára hajlamossá (másoláskor) és duplikált kódokká válhat.
Sokkal könnyebb lenne, ha lenne olyan Person
osztályunk, amelynek alapvető jellemzői vannak, például beszélgetés, séta, étkezés, alvás, és különleges képességekkel bővítenénk ezeket a funkciókat a karaktereink szerint. Ez öröklődéssel történik.
Használata öröklés, most már nem ugyanezt a kódot walk()
, talk()
és eat()
minden osztályban. Csak meg kell örökölni őket.
Tehát a MathTeacher
(származtatott osztály) esetében örökli egy Person
(alaposztály) összes tulajdonságát, és új funkciót ad hozzá teachMath()
. Hasonlóképpen, az Footballer
osztály számára örökli az osztály összes tulajdonságát, Person
és hozzáad egy új funkciót playFootball()
stb.
Ezáltal a kódja tisztább, érthetőbb és bővíthetőbbé válik.
Fontos megjegyezni: Az örökléssel való munkavégzés során minden származtatott osztálynak meg kell felelnie annak a feltételnek, hogy " alap " osztály vagy sem. A fenti példában MathTeacher
az a Person
, Footballer
az a Person
. Nem lehet valami hasonló, Businessman
a Business
.
Kotlin örökség
Próbáljuk meg a fenti vitát kódban megvalósítani:
nyitott osztály Személy (életkor: Közép) (// étkezési, beszélgetési, járási kód) osztály MathTeacher (életkor: Közép): Személy (életkor) (// a matematikatanár egyéb jellemzői) osztály Labdarúgó (életkor: Közép): Személy ( kor) (// a labdarúgó egyéb jellemzői) osztály üzletember (életkor: közép): személy (életkor) (// az üzletember egyéb jellemzői)
Itt Person
van egy alap osztályt, és az osztályok MathTeacher
, Footballer
és Businessman
származik a Person osztály.
Közlemény a kulcsszó open
előtt az alap osztály, Person
. Ez fontos.
Alapértelmezés szerint Kotlinban az osztályok véglegesek. Ha ismeri a Java-t, akkor tudja, hogy egy utolsó osztályt nem lehet alosztályba osztani. Ha a nyílt annotációt egy osztályon használja, a fordító lehetővé teszi új osztályok levezetését belőle.
Példa: Kotlin-öröklés
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() )
A program futtatásakor a kimenet a következő lesz:
A nevem Jack. 25 éves vagyok, általános iskolában tanítok. A nevem Cristiano. 29 éves vagyok, az LA Galaxy csapatában játszom.
Itt két osztály van, MathTeacher
és Footballer
az Person
osztályból származik .
Az Person
osztály elsődleges konstruktora két tulajdonságot deklarált: életkor és név, és rendelkezik inicializáló blokkkal. Az alaposztály iniciátorblokkjához (és tagfüggvényeihez) Person
a származtatott osztályok ( MathTeacher
és Footballer
) objektumai férhetnek hozzá .
Származtatott osztályok MathTeacher
és Footballer
saját tagfüggvényekkel teachMaths()
, playFootball()
ill. Ezek a funkciók csak a saját osztályuk tárgyaiból érhetők el.
Az MathTeacher
osztály t1 objektumának létrehozásakor
val t1 = MathTeacher (25, "Jack")
A paramétereket továbbítják az elsődleges konstruktornak. Kotlinban a init
blokkot az objektum létrehozásakor hívják meg. Mivel MathTeacher
az Person
osztályból származik , megkeresi az inicializáló blokkot az alaposztályban (Személy) és végrehajtja. Ha rendelkezett MathTeacher
volna init blokkkal, akkor a fordító a származtatott osztály init blokkját is végrehajtotta volna.
Ezután teachMaths()
az objektum függvényét utasítás t1
segítségével hívjuk meg t1.teachMaths()
.
A program hasonlóan működik, ha tárgya f1
az Footballer
osztályból. Végrehajtja az alaposztály init blokkját. Ezután playFootball()
az Footballer
osztály metódusát utasítás segítségével hívjuk meg f1.playFootball()
.
Fontos megjegyzések: Kotlin örökség
- Ha az osztály rendelkezik elsődleges konstruktorral, akkor az alapot az elsődleges konstruktor paramétereinek felhasználásával kell inicializálni. A fenti program, mind származó osztályon van két paraméter
age
, ésname
, és mindkét ezek a paraméterek inicializált elsődleges kivitelező a kiindulási osztályban.
Itt van egy másik példa: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") )
- Abban az esetben, ha nincs elsődleges konstruktor, minden alaposztálynak inicializálnia kell az alapot (szuper kulcsszóval), vagy egy másik konstruktorra kell delegálnia, amely ezt elvégzi. Például,
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) ( ) )
A tagok funkcióinak és tulajdonságainak felülírása
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
A super
kulcsszó segítségével egy származtatott osztályból hívhatja meg az alaposztály függvényeit (és hozzáférési tulajdonságait) . Itt van, hogyan:
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) )
A program futtatásakor a kimenet a következő lesz:
Korom 31. A hamis életkorom 26.