介面
介面是一種約定或協議,需要使用 interface 定義:
interface InputDevice { fun input(event: Any)}
介面不能有狀態,我們可以在介面中宣告一個類似"屬性"的變數 x,但它並不是一個屬性,相當於只是宣告 getX/setX 方法:
interface InputDevice { //val version: String = "default" // IDE報錯:Property initializers are not allowed in interfaces val version: String // 相當於定義getVersion()和setVersion()方法,但它不是屬性,因為介面沒有狀態 ...}
介面沒有構造器,因此無法像類那樣例項化,必須由類對其進行實現後使用:
fun main() { // val inputDevice = InputDevice() // IDE報錯:Interface InputDevice does not have constructors val myInputDevice = MyInputDevice("1.0") myInputDevice.input("")}class MyInputDevice(override val version: String) : InputDevice { override fun input(event: Any) { println("010101010101010101001010101010....") }}
實現介面需要使用 : 來連線,注意,因為介面沒有構造器,所以實現介面時不需要帶 ()。
介面之間是可以繼承的,子介面將擁有父介面的所有方法:
// USB輸入裝置interface USBInputDevice : InputDevice// 藍芽輸入裝置interface BLEInputDevice : InputDevice
另外,在 Kotlin 中介面方法可以預設實現:
interface InputDevice { ... fun onLowPower() { println("注意:當前電量低") }}
與 Kotlin 不同,Java 中的介面不支援預設實現。
抽象類抽象類可以理解為是實現了一部分協議的半成品,需要使用 abstract class 定義:
abstract class USBMouse(val name: String, override val version: String = "1.0") : USBInputDevice { override fun input(event: Any) { println("x , y ... ") } fun click(key: String) { println("點選了 $key 鍵") } abstract fun isSupport(os: String): Boolean}
可以看到,抽象類是有構造器的,構造器中的 val 或 var 引數會變成成員屬性,也就是說抽象類可以有狀態。抽象類 USBMouse 實現了 USBInputDevice 介面,並實現了 input()方法,說明抽象類可以有方法實現。當然了,抽象類中方法實現不依賴於介面,它本身就可以像類那樣定義自己的方法,如 click()。甚至它也可以像介面那樣定義沒有方法體的抽象方法 isSupport(),由具體子類去實現:
class LogitechMouse : USBMouse("羅技滑鼠") { override fun isSupport(os: String): Boolean { return when (os) { "windows" -> true "MacOS" -> true "iOS" -> false else -> false } }}
類繼承需要使用 : 來連線,注意,因為抽象類同普通類一樣擁有構造器(不管有無構造引數),所以實現抽象類時需要帶 ()。
抽象類無法直接例項化,必須要子類繼承後使用:
fun main() { // val mouse = USBMouse() // IDE報錯:Cannot create an instance of an abstract class val mouse = LogitechMouse() if (mouse.isSupport("windows")) { mouse.click("left") }}
單繼承多實現
Kotlin 不支援多繼承!但支援多實現!比如,羅技 M720 滑鼠本質是羅技滑鼠,擁有 USB 和 BLE 兩種連線功能:
class LogitechM720 : LogitechMouse(), USBInputDevice, BLEInputDevice {}fun main() { val usbInputDevice: USBInputDevice = LogitechM720() val bleInputDevice: BLEInputDevice = LogitechM720() val usbMouse: USBMouse = LogitechM720() val logitechMouse: LogitechMouse = LogitechM720()}
可以使用 介面或抽象類變數 接收 實現類例項。
抽象類和介面的共性與區別共性比較抽象,不能直接例項化有需要子類(實現類)實現的方法父類(介面)變數可以接收子類(實現類)的例項賦值區別抽象類有狀態,介面沒有狀態抽象類有方法實現,介面只能有無狀態的預設實現抽象類只能單繼承,介面可以多實現抽象類反映本質,介面體現能力