Kotlin教程笔记(10) - 面向对象之抽象类与接口

简介: Kotlin教程笔记(10) - 面向对象之抽象类与接口

本系列学习教程笔记属于详细讲解Kotlin语法的教程,需要快速学习Kotlin语法的小伙伴可以查看“简洁” 系列的教程

快速入门请阅读如下简洁教程:
Kotlin学习教程(一)
Kotlin学习教程(二)
Kotlin学习教程(三)
Kotlin学习教程(四)
Kotlin学习教程(五)
Kotlin学习教程(六)
Kotlin学习教程(七)
Kotlin学习教程(八)
Kotlin学习教程(九)
Kotlin学习教程(十)

imgKotlin - 面向对象之抽象类与接口

#接口

接口是一种约定或协议,需要使用 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()
}

可以使用 接口或抽象类变量 接收 实现类实例。

#抽象类和接口的共性与区别

共性 比较抽象,不能直接实例化
有需要子类(实现类)实现的方法
父类(接口)变量可以接收子类(实现类)的实例赋值
区别 抽象类有状态,接口没有状态
抽象类有方法实现,接口只能有无状态的默认实现
抽象类只能单继承,接口可以多实现
抽象类反映本质,接口体现能力
相关文章
|
1天前
|
Java 物联网 Kotlin
Kotlin - 面向对象之抽象类与接口
Kotlin - 面向对象之抽象类与接口
25 11
|
1天前
|
数据安全/隐私保护 Kotlin
|
1天前
|
Kotlin
Kotlin教程笔记(9)- 参数与异常
Kotlin教程笔记(9)- 参数与异常
18 3
|
1天前
|
Java Kotlin 索引
Kotlin教程笔记(8)- 分支与循环
Kotlin教程笔记(8)- 分支与循环
17 2
|
Kotlin
【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )(二)
【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )(二)
277 0
|
Java Kotlin
【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )(一)
【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )(一)
172 0
|
1月前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
53 1
|
2月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
43 4
|
3月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
112 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
3月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
44 8