2-6-1 快速掌握Kotlin-语言的接口定义

Kotlin 接口定义

Kotlin 接口是一种强大的抽象机制,它允许定义方法、属性、默认实现,并且支持多继承。以下是 Kotlin 接口的完整指南:

1. 基本接口定义

简单接口

kotlin 复制代码
// 定义接口
interface Drawable {
    fun draw()  // 抽象方法
}

// 实现接口
class Circle : Drawable {
    override fun draw() {
        println("绘制圆形")
    }
}

带属性的接口

kotlin 复制代码
interface Shape {
    val name: String  // 抽象属性
    
    val description: String
        get() = "这是一个形状"  // 带 getter 的属性
}

class Square : Shape {
    override val name: String = "正方形"
    
    // 可以重写 description 属性
    override val description: String
        get() = "这是一个四边相等的形状"
}

2. 接口中的方法

抽象方法和默认实现

kotlin 复制代码
interface Vehicle {
    // 抽象方法(必须被实现)
    fun start()
    
    // 带默认实现的方法(可选重写)
    fun stop() {
        println("车辆停止")
    }
    
    // 也可以有具体实现的方法体
    fun honk() = println("嘟嘟!")
}

class Car : Vehicle {
    override fun start() {
        println("汽车启动")
    }
    
    // 可以选择重写 stop(),也可以使用默认实现
    override fun stop() {
        println("汽车紧急制动")
    }
    
    // 不重写 honk(),使用接口中的默认实现
}

私有方法(Kotlin 1.7+)

kotlin 复制代码
interface DatabaseAccess {
    fun save(data: String) {
        validate(data)
        println("保存数据: $data")
    }
    
    private fun validate(data: String) {  // 接口中的私有方法
        require(data.isNotBlank()) { "数据不能为空" }
    }
}

3. 接口中的属性

各种属性类型

kotlin 复制代码
interface User {
    // 抽象属性(必须被实现)
    val username: String
    
    // 带 getter 的属性
    val displayName: String
        get() = username.uppercase()
    
    // 可变属性
    var email: String
    
    // 常量(使用伴生对象)
    companion object {
        const val MIN_USERNAME_LENGTH = 3
    }
}

class RegularUser(override val username: String) : User {
    override var email: String = ""
    
    // 可以重写 displayName
    override val displayName: String
        get() = "用户: ${username.lowercase()}"
}

4. 接口继承

接口继承接口

kotlin 复制代码
interface Clickable {
    fun click()
}

interface Focusable : Clickable {
    fun focus()
    fun showOff() = println("我是可聚焦的!")
}

class Button : Focusable {
    override fun click() {
        println("按钮被点击")
    }
    
    override fun focus() {
        println("按钮获得焦点")
    }
    
    // 可以选择重写 showOff() 或不重写
}

多接口继承

kotlin 复制代码
interface A {
    fun foo() = println("A.foo")
}

interface B {
    fun foo() = println("B.foo")
    fun bar() = println("B.bar")
}

class C : A, B {
    // 必须重写 foo() 来解决冲突
    override fun foo() {
        // 调用特定父接口的实现
        super<A>.foo()
        super<B>.foo()
        println("C.foo")
    }
    
    // 不需要重写 bar(),因为只有一个实现
}

5. 函数式接口(SAM接口)

单抽象方法接口

kotlin 复制代码
// 使用 fun interface 声明(Kotlin 1.4+)
fun interface StringProcessor {
    fun process(input: String): String
}

// 传统方式
interface OnClickListener {
    fun onClick(view: View)
}

// 使用 lambda 表达式实现
val processor = StringProcessor { it.uppercase() }
val listener = OnClickListener { println("点击了 $it") }

// 在函数参数中使用
fun setOnClickListener(listener: OnClickListener) {
    // ...
}

// 调用时可以传递 lambda
setOnClickListener { view -> println("点击") }

Java 函数式接口互操作

kotlin 复制代码
// Java 中的函数式接口
// @FunctionalInterface
// public interface Runnable { void run(); }

val runnable = Runnable { println("在后台运行") }
Thread(runnable).start()

// 或者直接使用
Thread { println("简洁写法") }.start()

6. 接口与抽象类的比较

kotlin 复制代码
// 接口
interface AnimalInterface {
    val name: String
    fun makeSound()
    
    fun eat() {  // 可以有默认实现
        println("$name 正在进食")
    }
}

// 抽象类
abstract class AnimalAbstract {
    abstract val name: String
    abstract fun makeSound()
    
    open fun eat() {  // 需要 open 关键字
        println("$name 正在进食")
    }
    
    // 抽象类可以有状态
    var age: Int = 0
    
    // 可以有构造函数
    constructor(name: String)
}

// 实现差异
class DogInterface : AnimalInterface {
    override val name: String = "狗狗"
    override fun makeSound() = println("汪汪!")
}

class DogAbstract : AnimalAbstract("狗狗") {
    override val name: String = "狗狗"
    override fun makeSound() = println("汪汪!")
}

7. 接口委托

使用 by 关键字委托实现

kotlin 复制代码
interface Repository {
    fun save(data: String)
    fun load(id: String): String?
}

class DatabaseRepository : Repository {
    override fun save(data: String) {
        println("保存到数据库: $data")
    }
    
    override fun load(id: String): String? {
        println("从数据库加载: $id")
        return "数据"
    }
}

// 委托给 DatabaseRepository
class CachedRepository(private val repository: Repository) : Repository by repository {
    private val cache = mutableMapOf<String, String>()
    
    // 只重写需要定制的方法
    override fun load(id: String): String? {
        return cache[id] ?: repository.load(id)?.also {
            cache[id] = it
        }
    }
    
    // 新增方法
    fun clearCache() {
        cache.clear()
    }
}

属性委托到接口

kotlin 复制代码
interface Logger {
    fun log(message: String)
}

class ConsoleLogger : Logger {
    override fun log(message: String) {
        println("控制台日志: $message")
    }
}

class Service(logger: Logger) {
    private val logger: Logger by lazy { logger }
    
    fun doWork() {
        logger.log("开始工作")
        // 工作逻辑
        logger.log("工作完成")
    }
}

8. 接口中的内联方法

kotlin 复制代码
interface JsonSerializable {
    fun toJson(): String
    
    // 内联方法
    inline fun printJson() {
        println(toJson())
    }
}

data class Person(val name: String, val age: Int) : JsonSerializable {
    override fun toJson(): String {
        return """{"name": "$name", "age": $age}"""
    }
}

// 使用
val person = Person("Alice", 30)
person.printJson()  // 内联展开

9. 接口中的扩展函数

kotlin 复制代码
interface Sortable<T> {
    fun compare(other: T): Int
}

// 为接口定义扩展函数
fun <T : Sortable<T>> List<T>.sorted(): List<T> {
    return this.sortedWith { a, b -> a.compare(b) }
}

// 为接口定义扩展属性
val Sortable<*>.hash: Int
    get() = hashCode()

// 使用示例
data class Product(val name: String, val price: Double) : Sortable<Product> {
    override fun compare(other: Product): Int {
        return price.compareTo(other.price)
    }
}

val products = listOf(
    Product("A", 100.0),
    Product("B", 50.0),
    Product("C", 75.0)
)

val sorted = products.sorted()  // 使用扩展函数

10. 接口的实用模式

标记接口

kotlin 复制代码
// 标记接口(没有任何方法)
interface Serializable

// 使用
data class Document(val content: String) : Serializable

fun saveIfSerializable(obj: Any) {
    if (obj is Serializable) {
        println("保存对象: $obj")
    }
}

构建器模式接口

kotlin 复制代码
interface Builder<T> {
    fun build(): T
}

class CarBuilder : Builder<Car> {
    private var color = "红色"
    private var wheels = 4
    
    fun setColor(color: String) = apply { this.color = color }
    fun setWheels(wheels: Int) = apply { this.wheels = wheels }
    
    override fun build(): Car {
        return Car(color, wheels)
    }
}

data class Car(val color: String, val wheels: Int)

// 使用
val car = CarBuilder()
    .setColor("蓝色")
    .setWheels(4)
    .build()

策略模式接口

kotlin 复制代码
interface PaymentStrategy {
    fun pay(amount: Double): Boolean
}

class CreditCardPayment : PaymentStrategy {
    override fun pay(amount: Double): Boolean {
        println("信用卡支付: $$amount")
        return true
    }
}

class PayPalPayment : PaymentStrategy {
    override fun pay(amount: Double): Boolean {
        println("PayPal支付: $$amount")
        return true
    }
}

class ShoppingCart(private var paymentStrategy: PaymentStrategy) {
    fun checkout(amount: Double) {
        paymentStrategy.pay(amount)
    }
    
    fun changeStrategy(strategy: PaymentStrategy) {
        paymentStrategy = strategy
    }
}

11. 接口的协变和逆变

kotlin 复制代码
// 协变接口(out 关键字)
interface Producer<out T> {
    fun produce(): T
}

// 逆变接口(in 关键字)
interface Consumer<in T> {
    fun consume(item: T)
}

// 使用示例
class FruitProducer : Producer<Fruit> {
    override fun produce(): Fruit = Fruit()
}

class AppleProducer : Producer<Apple> {
    override fun produce(): Apple = Apple()
}

open class Fruit
class Apple : Fruit()

fun useProducer(producer: Producer<Fruit>) {
    val fruit: Fruit = producer.produce()
}

// 协变允许 Producer<Apple> 赋值给 Producer<Fruit>
val fruitProducer: Producer<Fruit> = AppleProducer()

12. 接口的最佳实践

kotlin 复制代码
// 1. 单一职责原则
interface Savable {
    fun save()
}

interface Loadable {
    fun load()
}

// 2. 接口隔离原则(不要强迫客户端依赖它们不用的方法)
interface Printer {
    fun print()
}

interface Scanner {
    fun scan()
}

// 3. 使用默认实现减少样板代码
interface Repository<T> {
    fun save(item: T)
    fun findById(id: String): T?
    fun findAll(): List<T>
    
    // 默认实现
    fun existsById(id: String): Boolean {
        return findById(id) != null
    }
}

// 4. 使用函数式接口简化回调
fun interface OnSuccess<T> {
    fun onSuccess(result: T)
}

fun <T> doAsync(
    operation: () -> T,
    onSuccess: OnSuccess<T>
) {
    val result = operation()
    onSuccess.onSuccess(result)
}

// 使用
doAsync(
    operation = { "结果" },
    onSuccess = { println("成功: $it") }
)

总结

Kotlin 接口提供了比 Java 接口更强大的功能:

  • 默认方法实现:减少实现类的样板代码
  • 属性支持:可以定义抽象属性和带 getter/setter 的属性
  • 多继承:一个类可以实现多个接口
  • 函数式接口:支持 SAM 转换,简化回调
  • 私有方法:Kotlin 1.7+ 支持接口中的私有方法
  • 委托模式 :使用 by 关键字委托接口实现

接口在 Kotlin 中是实现抽象、多态和解耦代码的重要工具。

相关推荐
LING33 分钟前
RN容器启动优化实践
android·react native
恋猫de小郭3 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker8 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴8 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭18 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab19 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin