Dalam artikel ini, anda akan belajar mengenai warisan. Lebih khusus lagi, apa itu warisan dan bagaimana melaksanakannya di Kotlin (dengan bantuan contoh).
Warisan adalah salah satu ciri utama pengaturcaraan berorientasikan objek. Ini membolehkan pengguna membuat kelas baru (kelas turunan) dari kelas yang ada (kelas asas).
Kelas yang diturunkan mewarisi semua ciri dari kelas asas dan boleh mempunyai ciri tambahan sendiri.
Sebelum memperincikan maklumat mengenai warisan Kotlin, kami mengesyorkan anda memeriksa kedua artikel ini:
- Kelas dan Objek Kotlin
- Pembina Utama Kotlin
Mengapa harta pusaka?
Andaikan, dalam aplikasi anda, anda memerlukan tiga watak - seorang guru matematik , pemain bola sepak dan ahli perniagaan .
Oleh kerana, semua watak adalah orang, mereka boleh berjalan dan bercakap. Namun, mereka juga mempunyai beberapa kemahiran khas. Seorang guru matematik boleh mengajar matematik , seorang pemain bola sepak boleh bermain bola sepak dan seorang pengusaha dapat menjalankan perniagaan .
Anda secara individu boleh membuat tiga kelas yang boleh berjalan, bercakap dan melaksanakan kemahiran khas mereka.
Di setiap kelas, anda akan menyalin kod yang sama untuk berjalan dan bercakap untuk setiap watak.
Sekiranya anda ingin menambahkan ciri baru - makan, anda perlu menerapkan kod yang sama untuk setiap watak. Ini mudah menjadi rawan ralat (semasa menyalin) dan kod pendua.
Akan lebih mudah jika kita mempunyai Person
kelas dengan ciri-ciri asas seperti bercakap, berjalan kaki, makan, tidur, dan menambahkan kemahiran khas pada ciri-ciri tersebut mengikut watak kita. Ini dilakukan dengan menggunakan warisan.
Dengan menggunakan warisan, sekarang anda tidak menerapkan kod yang sama untuk walk()
, talk()
dan eat()
untuk setiap kelas. Anda hanya perlu mewarisi mereka.
Oleh itu, untuk MathTeacher
(kelas turunan), anda mewarisi semua ciri Person
(kelas asas) dan menambah ciri baru teachMath()
. Begitu juga, untuk Footballer
kelas, anda mewarisi semua ciri Person
kelas dan menambah ciri baru playFootball()
dan sebagainya.
Ini menjadikan kod anda lebih bersih, difahami dan dapat diperluas.
Adalah penting untuk ingat: Apabila bekerja dengan warisan, setiap kelas yang diperolehi harus memenuhi syarat sama ada ia "adalah" kelas asas atau tidak. Dalam contoh di atas, MathTeacher
adalah a Person
, Footballer
adalah a Person
. Anda tidak boleh mempunyai sesuatu seperti, Businessman
adalah Business
.
Pewarisan Kotlin
Mari cuba melaksanakan perbincangan di atas dalam kod:
kelas terbuka Orang (umur: Int) (// kod untuk makan, bercakap, berjalan) kelas MathTeacher (umur: Int): Orang (umur) (// ciri lain guru matematik) kelas Pemain bola sepak (umur: Int): Orang ( umur) (// ciri lain pemain bola sepak) kelas Pengusaha (umur: Int): Orang (umur) (// ciri lain ahli perniagaan)
Di sini, Person
adalah kelas asas, dan kelas MathTeacher
, Footballer
dan Businessman
berasal dari kelas Orang Yang.
Perhatikan, kata kunci open
sebelum kelas asas , Person
. Ianya penting.
Secara lalai, kelas di Kotlin adalah muktamad. Sekiranya anda biasa dengan Java, anda tahu bahawa kelas akhir tidak dapat dikelaskan dalam kelas. Dengan menggunakan anotasi terbuka pada kelas, penyusun membolehkan anda memperoleh kelas baru darinya.
Contoh: Warisan Kotlin
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() )
Semasa anda menjalankan program, outputnya adalah:
Nama saya Jack. Umur saya 25 tahun saya mengajar di sekolah rendah. Nama saya Cristiano. Umur saya 29 tahun saya bermain untuk LA Galaxy.
Di sini, dua kelas MathTeacher
dan Footballer
berasal dari Person
kelas.
Pembina utama Person
kelas menyatakan dua sifat: umur dan nama, dan ia mempunyai blok penginisialisasi. Blok initilizer (dan fungsi anggota) kelas asas Person
dapat diakses oleh objek kelas turunan ( MathTeacher
dan Footballer
).
Berasal dari kelas MathTeacher
dan Footballer
mempunyai fungsi ahli masing teachMaths()
- playFootball()
masing dan masing - masing. Fungsi-fungsi ini hanya dapat dicapai dari objek kelas masing-masing.
Apabila objek t1 MathTeacher
kelas dibuat,
val t1 = MathTeacher (25, "Jack")
Parameter diteruskan ke konstruktor utama. Di Kotlin, init
blok disebut ketika objek dibuat. Oleh kerana, MathTeacher
berasal dari Person
kelas, ia mencari blok penginisialisasi pada kelas dasar (Person) dan melaksanakannya. Sekiranya MathTeacher
blok init, penyusun juga akan melaksanakan blok init dari kelas turunan.
Seterusnya, teachMaths()
fungsi untuk objek t1
dipanggil menggunakan t1.teachMaths()
pernyataan.
Program ini berfungsi sama apabila objek f1
daripada Footballer
kelas dicipta. Ia melaksanakan blok init kelas asas. Kemudian, playFootball()
kaedah Footballer
kelas dipanggil menggunakan pernyataan f1.playFootball()
.
Nota Penting: Kotlin Warisan
- Sekiranya kelas mempunyai konstruktor utama, asas mesti dimulakan dengan menggunakan parameter pembina utama. Dalam program di atas, kedua-dua kelas turunan mempunyai dua parameter
age
danname
, dan kedua-dua parameter ini diinisialisasi dalam konstruktor primer di kelas asas.
Inilah contoh lain: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") )
- Sekiranya tiada konstruktor utama, setiap kelas asas harus menginisialisasi asas (menggunakan kata kunci super), atau mewakilkan kepada pembina lain yang melakukannya. Sebagai contoh,
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) ( ) )
Menurunkan Fungsi dan Sifat Ahli
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
Anda boleh memanggil fungsi (dan mengakses sifat) kelas asas dari kelas turunan menggunakan super
kata kunci. Ini caranya:
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) )
Semasa anda menjalankan program, outputnya adalah:
Umur saya 31. Umur palsu saya ialah 26.