数码知识屋
霓虹主题四 · 更硬核的阅读氛围

Kotlin接口与抽象类:实际开发中的选择与使用

发布时间:2026-01-02 00:50:30 阅读:57 次

接口和抽象的基本定义

Kotlin 作为现代 Android 开发的主流语言,提供了接口(interface)和抽象类(abstract class)两种机制来实现代码复用和多态。虽然它们都能定义方法模板,但适用场景并不相同。

接口用于声明行为规范,所有方法默认是公开的抽象方法,也可以包含带实现的方法。抽象类则更像一个“半成品”类,可以包含抽象方法、具体实现,还能保存状态(即成员变量)。

接口的写法示例

比如我们想让多个类都具备“可点击”的能力:

interface Clickable {
fun onClick()

fun onLongClick(): Boolean {
return false
}
}

这里 onClick 是抽象方法,子类必须实现;而 onLongClick 提供了默认实现,子类可以选择性重写。

抽象类的使用场景

假设我们开发一个天气应用,不同城市的天气逻辑有共性也有差异。这时候用抽象类就更合适:

abstract class WeatherCalculator {
protected var baseTemp = 20

abstract fun calculateToday(): Double

open fun calculateWeekAverage(): Double {
return baseTemp + 1.5
}
}

子类继承时可以直接使用 baseTemp,也能选择是否重写 calculateWeekAverage。这种带状态和部分实现的结构,接口无法胜任。

关键区别点

接口不能保存状态,也就是不能有非 const 的属性;抽象类可以。接口支持多实现,一个类能实现多个接口;但只能继承一个抽象类。这就像一个人可以同时“会游泳”“会开车”,但出身家庭只能有一个。

从 Kotlin 1.2 开始,接口允许有默认实现,这让它比 Java 的接口更强大,也更容易和抽象类混淆。但在需要共享字段或构造逻辑时,抽象类仍是唯一选择。

实际项目怎么选

在写一个登录模块时,如果只是定义“登录”“登出”这些动作,用接口更灵活:

interface AuthProvider {
fun login(username: String, password: String): Boolean
fun logout()
}

但如果要统一处理 token 刷新、请求头添加等逻辑,用抽象类封装公共代码会减少重复:

abstract class BaseApiService {
protected val headers = mutableMapOf<String, String>()

init {
headers["Content-Type"] = "application/json"
}

abstract fun fetchData(): String
}

多数情况下,优先考虑接口,只有当需要共享状态或复杂初始化时才用抽象类。这样代码更干净,也更容易测试和扩展。