接口與抽象類的區別
同樣在Kotlin中也有接口的概念,與Java不同的是,Kotlin中的接口可以定義變量,但是不能爲變量提供構造函數,也可以實現函數體,如果沒有實現的函數,默認抽象,不需要使用abstract
來定義。
而抽象類中,可以爲定義的變量提供構造函數進行賦值,而如果沒有賦值的變量需要使用abstract
來定義,而沒有實現的函數也需要使用abstract
來定義
接口
Kotlin中的接口可以定義變量,也允許實現函數體。但是不允許有構造函數,並且抽象函數也不需要使用abstract
關鍵字定義。
但是在實現接口的子類中必須使用override
來覆蓋接口中所定義的變量以及抽象函數。而提供了get
方法的變量,也就不需要子類實現了。
interface IPerson { val mName: String var mAge: Int val mDump: String get() = "$mName...$mAge" fun print() { Log.e("IPerson", "mName:$mName...mAge:$mAge") } fun walk() }
子類實現:
class Child(name: String, age: Int = 18) : IPerson { // 必須要重載接口中定義的變量 override var mName = name override var mAge = age override fun walk() { Log.e("Child", "Child Walk called:$mName...$mAge") } }
抽象類
抽象類中定義的變量如果沒有在構造函數中賦值的話,則需要使用abstract
定義,而函數也一樣,如果沒有實現,則需要使用abstract
來定義
abstract class AbsPerson(name: String) { var mName: String = name abstract var mAge: Int fun print() { Log.e("IPerson", "mName:$mName...mAge:$mAge") } abstract fun walk() }
子類實現:
open class Child(name: String, age: Int = 18) : AbsPerson(name) { override var mAge = age override fun walk() { Log.e("Child", "Child Walk called:$mName...$mAge") } }
繼承
在Kotlin中,如果沒有定義abstract
的抽象來定義類或者函數的話,那麼就需要使用open
關鍵字來定義才允許讓子類繼承或者重載函數
因爲如果沒有使用open
定義的話,則默認會添加final
標誌位,不可重寫。
open class Child(name: String, age: Int = 18) : AbsPerson(name) { override var mAge = age override fun walk() { Log.e("Child", "Child Walk called:$mName...$mAge") } protected open fun run() { Log.e("Child", "Child can't Run:$mName...$mAge") } }
子類實現
class Teenager(name: String) : Child(name) { override fun run() { super.run() Log.e("Teenager", "Teenager can run:$mName...$mAge") } }
其中,
protected
僅僅只代表訪問權限,只有子類可以訪問,open
則代表是否可以重寫以及繼承。如果一個普通的類沒有使用open
來定義類和函數的話,則無法繼承也無法重寫函數