Bu makalede, kalıtım hakkında bilgi edineceksiniz. Daha spesifik olarak, kalıtım nedir ve Kotlin'de nasıl uygulanacağı (örnekler yardımıyla).
Kalıtım, nesne yönelimli programlamanın temel özelliklerinden biridir. Kullanıcının mevcut bir sınıftan (temel sınıf) yeni bir sınıf (türetilmiş sınıf) oluşturmasına izin verir.
Türetilmiş sınıf, tüm özellikleri temel sınıftan devralır ve kendi ek özelliklerine sahip olabilir.
Kotlin mirası ile ilgili ayrıntılara girmeden önce şu iki makaleye göz atmanızı tavsiye ederiz:
- Kotlin Sınıfı ve Nesneleri
- Kotlin Birincil Yapıcı
Neden miras?
Diyelim ki başvurunuzda üç karakter istiyorsunuz - bir matematik öğretmeni , bir futbolcu ve bir işadamı .
Karakterlerin tamamı kişi olduğu için yürüyebilir ve konuşabilirler. Bununla birlikte, bazı özel becerileri de vardır. Bir matematik öğretmeni olabilir matematik öğretmek , bir futbolcu olabilir futbol oynamak ve iş adamı olabilir bir işletmeyi .
Özel becerilerini yürüyebilecek, konuşabilecek ve gerçekleştirebilecek üç sınıf oluşturabilirsiniz.
Sınıfların her birinde, her karakter için aynı yürüyüş ve konuşma kodunu kopyalıyorsunuz.
Yeni bir özellik eklemek istiyorsanız - eat, her karakter için aynı kodu uygulamanız gerekir. Bu, kolayca hataya açık hale gelebilir (kopyalarken) ve yinelenen kodlar olabilir.
Person
Karakterlerimize göre konuşma, yürüyüş, yemek, uyku gibi temel özelliklere sahip bir sınıfımız olsaydı ve bu özelliklere özel beceriler katarsak çok daha kolay olurdu . Bu, kalıtım kullanılarak yapılır.
Devralma kullanarak, artık sizin için aynı kodu uygulayacak yok walk()
, talk()
ve eat()
her sınıf için. Sadece onları miras almalısın .
Yani, MathTeacher
(türetilmiş sınıf) için, bir Person
(temel sınıf) 'ın tüm özelliklerini miras alırsınız ve yeni bir özellik eklersiniz teachMath()
. Aynı şekilde, Footballer
sınıf için, sınıfın tüm özelliklerini devralırsınız Person
ve yeni bir özellik eklersiniz playFootball()
vb.
Bu, kodunuzu daha temiz, anlaşılır ve genişletilebilir hale getirir.
Unutulmaması önemlidir: Kalıtımla çalışırken, türetilmiş her sınıf, "bir" temel sınıf olup olmadığı koşulunu karşılamalıdır . Yukarıdaki örnekte MathTeacher
, a Person
, Footballer
a'dır Person
. Gibi bir şeye sahip olamazsınız Businessman
, a Business
.
Kotlin mirası
Yukarıdaki tartışmayı kodda uygulamaya çalışalım:
açık sınıf Kişi (yaş: Orta) (// yemek, konuşma, yürüme kodu) sınıf MathTeacher (yaş: Orta): Kişi (yaş) (// matematik öğretmeninin diğer özellikleri) sınıfı Futbolcu (yaş: Orta): Kişi ( yaş) (// futbolcunun diğer özellikleri) sınıfı İşadamı (yaş: İnt): Kişi (yaş) (// işadamının diğer özellikleri)
Burada, Person
bir temel sınıftır ve sınıfları MathTeacher
, Footballer
ve Businessman
Kişi sınıfından türetilir.
Dikkat edin, open
temel sınıftan önceki anahtar kelime Person
,. Bu önemli.
Varsayılan olarak, Kotlin'deki sınıflar kesindir. Java'ya aşina iseniz, son bir sınıfın alt sınıflara ayrılamayacağını bilirsiniz. Bir sınıf üzerinde açık ek açıklamayı kullanarak, derleyici ondan yeni sınıflar türetmenize izin verir.
Örnek: Kotlin Mirası
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() )
Programı çalıştırdığınızda, çıktı:
Benim adım Jack. Yaşım 25, ilkokulda öğretmenlik yapıyorum. Benim adım Cristiano. Yaşım 29, LA Galaxy için oynuyorum.
Burada iki sınıf MathTeacher
ve sınıftan Footballer
türetilmiştir Person
.
Person
Sınıfın birincil kurucusu iki özellik bildirdi: age ve name ve bir başlatıcı bloğu var. Temel sınıfın başlatma bloğuna (ve üye işlevlerine) Person
türetilmiş sınıfların ( MathTeacher
ve Footballer
) nesneleri tarafından erişilebilir .
Sınıfları Türetilmiş MathTeacher
ve Footballer
kendi üye işlevlere sahiptir teachMaths()
ve playFootball()
sırasıyla. Bu işlevlere yalnızca ilgili sınıflarının nesnelerinden erişilebilir.
MathTeacher
Sınıfın t1 nesnesi oluşturulduğunda,
val t1 = MathTeacher (25, "Jack")
Parametreler birincil kurucuya aktarılır. Kotlin'de, init
nesne oluşturulduğunda blok çağrılır. Yana MathTeacher
türetildiği Person
sınıf, bu başlatıcısı temel sınıf blok (kişi) ve çalıştırır bu arar. Eğer MathTeacher
init bloğu olsaydı, derleyici türetilmiş sınıfın init bloğunu da çalıştırırdı.
Daha sonra, teachMaths()
nesne işlevi t1
using t1.teachMaths()
deyimi olarak adlandırılır .
Program f1
, Footballer
sınıf nesnesi oluşturulduğunda benzer şekilde çalışır . Temel sınıfın init bloğunu yürütür. Daha sonra, sınıfın playFootball()
yöntemi Footballer
using deyimi olarak adlandırılır f1.playFootball()
.
Önemli Notlar: Kotlin Mirası
- Sınıfın birincil kurucusu varsa, temel oluşturucunun parametreleri kullanılarak başlatılmalıdır. Yukarıdaki programda, her iki türetilmiş sınıfın iki parametresi vardır
age
vename
bu parametrelerin her ikisi de temel sınıftaki birincil kurucuda başlatılır.
İşte başka bir örnek: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") )
- Birincil kurucu olmaması durumunda, her temel sınıfın tabanı başlatması (super anahtar sözcüğü kullanarak) veya bunu yapan başka bir kurucuya delege etmesi gerekir. Örneğin,
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) ( ) )
Üye İşlevlerini ve Özelliklerini Geçersiz Kılma
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
super
Anahtar sözcük kullanarak türetilmiş bir sınıftan temel sınıfın işlevlerini (ve özelliklerine erişebilirsiniz) çağırabilirsiniz . Bunu nasıl yapacağınız aşağıda açıklanmıştır:
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) )
Programı çalıştırdığınızda, çıktı:
Yaşım 31. Sahte yaşım 26.