接口和抽象类
概述
接口和抽象类是Kotlin面向对象编程的重要概念。它们提供了代码抽象、多态性和契约定义的能力。本章将详细介绍接口的定义、实现、抽象类的使用,以及它们在实际开发中的应用。
接口基础
接口定义和实现
kotlin
// 基本接口定义
interface Drawable {
// 抽象方法
fun draw()
// 带默认实现的方法
fun getInfo(): String = "这是一个可绘制对象"
// 抽象属性
val color: String
// 带默认实现的属性
val isVisible: Boolean
get() = true
}
// 实现接口
class Circle(override val color: String, val radius: Double) : Drawable {
override fun draw() {
println("绘制一个${color}的圆,半径为${radius}")
}
override fun getInfo(): String {
return "圆形:颜色=${color},半径=${radius}"
}
}
class Rectangle(override val color: String, val width: Double, val height: Double) : Drawable {
override fun draw() {
println("绘制一个${color}的矩形,${width}x${height}")
}
// 重写属性
override val isVisible: Boolean = width > 0 && height > 0
}
fun main() {
val shapes: List<Drawable> = listOf(
Circle("红色", 5.0),
Rectangle("蓝色", 10.0, 8.0),
Rectangle("绿色", 0.0, 5.0) // 不可见的矩形
)
shapes.forEach { shape ->
println(shape.getInfo())
println("可见性: ${shape.isVisible}")
shape.draw()
println()
}
}多接口实现
kotlin
interface Movable {
fun move(x: Int, y: Int)
val speed: Double
}
interface Rotatable {
fun rotate(angle: Double)
val rotationSpeed: Double
get() = 1.0
}
interface Scalable {
fun scale(factor: Double)
}
// 实现多个接口
class GameObject(
override val color: String,
override val speed: Double
) : Drawable, Movable, Rotatable, Scalable {
private var x = 0
private var y = 0
private var rotation = 0.0
private var scaleX = 1.0
private var scaleY = 1.0
override fun draw() {
println("绘制游戏对象在位置($x, $y),旋转${rotation}度,缩放${scaleX}x${scaleY}")
}
override fun move(x: Int, y: Int) {
this.x += x
this.y += y
println("移动到位置(${this.x}, ${this.y})")
}
override fun rotate(angle: Double) {
rotation += angle
println("旋转${angle}度,当前角度${rotation}度")
}
override fun scale(factor: Double) {
scaleX *= factor
scaleY *= factor
println("缩放${factor}倍,当前缩放${scaleX}x${scaleY}")
}
fun getPosition() = Pair(x, y)
fun getRotation() = rotation
fun getScale() = Pair(scaleX, scaleY)
}
fun main() {
val gameObject = GameObject("紫色", 5.0)
// 使用不同接口的功能
gameObject.draw()
gameObject.move(10, 20)
gameObject.rotate(45.0)
gameObject.scale(1.5)
gameObject.draw()
// 多态性
val drawable: Drawable = gameObject
val movable: Movable = gameObject
val rotatable: Rotatable = gameObject
println("作为Drawable: ${drawable.getInfo()}")
println("移动速度: ${movable.speed}")
println("旋转速度: ${rotatable.rotationSpeed}")
}接口的高级特性
接口中的方法冲突解决
kotlin
interface A {
fun foo() {
println("A.foo()")
}
fun bar()
}
interface B {
fun foo() {
println("B.foo()")
}
fun bar() {
println("B.bar()")
}
}
// 解决方法冲突
class C : A, B {
override fun foo() {
super<A>.foo() // 调用A的实现
super<B>.foo() // 调用B的实现
println("C.foo()") // 自己的实现
}
override fun bar() {
super<B>.bar() // 选择B的实现
}
}
fun main() {
val c = C()
c.foo()
c.bar()
}函数式接口 (SAM接口)
kotlin
// 函数式接口(Single Abstract Method)
fun interface StringProcessor {
fun process(input: String): String
}
fun interface NumberValidator {
fun validate(number: Int): Boolean
}
fun interface EventHandler<T> {
fun handle(event: T)
}
// 使用函数式接口
class TextProcessor {
fun processText(text: String, processor: StringProcessor): String {
return processor.process(text)
}
fun validateNumbers(numbers: List<Int>, validator: NumberValidator): List<Int> {
return numbers.filter { validator.validate(it) }
}
}
fun main() {
val textProcessor = TextProcessor()
// 使用lambda表达式实现函数式接口
val upperCaseProcessor = StringProcessor { it.uppercase() }
val trimProcessor = StringProcessor { it.trim() }
val text = " hello world "
println("原文: '$text'")
println("大写: '${textProcessor.processText(text, upperCaseProcessor)}'")
println("去空格: '${textProcessor.processText(text, trimProcessor)}'")
// 数字验证
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenValidator = NumberValidator { it % 2 == 0 }
val positiveValidator = NumberValidator { it > 0 }
println("偶数: ${textProcessor.validateNumbers(numbers, evenValidator)}")
println("正数: ${textProcessor.validateNumbers(numbers, positiveValidator)}")
// 事件处理
val stringHandler: EventHandler<String> = EventHandler { event ->
println("处理字符串事件: $event")
}
val intHandler: EventHandler<Int> = EventHandler { event ->
println("处理整数事件: $event")
}
stringHandler.handle("用户登录")
intHandler.handle(404)
}抽象类
抽象类定义和使用
kotlin
// 抽象类
abstract class Animal(val name: String, val species: String) {
// 具体属性
var age: Int = 0
// 抽象属性
abstract val habitat: String
// 具体方法
fun eat(food: String) {
println("$name 正在吃 $food")
}
fun sleep() {
println("$name 正在睡觉")
}
// 抽象方法
abstract fun makeSound()
abstract fun move()
// 带默认实现的开放方法
open fun getInfo(): String {
return "$name 是一只 $species,年龄 $age 岁,栖息地:$habitat"
}
}
// 继承抽象类
class Dog(name: String) : Animal(name, "犬科动物") {
override val habitat = "陆地"
override fun makeSound() {
println("$name 汪汪叫")
}
override fun move() {
println("$name 在跑步")
}
// 特有方法
fun wagTail() {
println("$name 摇尾巴")
}
}
class Fish(name: String, val waterType: String) : Animal(name, "鱼类") {
override val habitat = "${waterType}水域"
override fun makeSound() {
println("$name 吐泡泡")
}
override fun move() {
println("$name 在游泳")
}
override fun getInfo(): String {
return super.getInfo() + ",水域类型:$waterType"
}
fun swim() {
println("$name 在水中游泳")
}
}
class Bird(name: String, val canFly: Boolean) : Animal(name, "鸟类") {
override val habitat = "天空和树木"
override fun makeSound() {
println("$name 啾啾叫")
}
override fun move() {
if (canFly) {
println("$name 在飞翔")
} else {
println("$name 在地上走")
}
}
fun fly() {
if (canFly) {
println("$name 展翅高飞")
} else {
println("$name 不会飞")
}
}
}
fun main() {
val animals: List<Animal> = listOf(
Dog("旺财").apply { age = 3 },
Fish("小金", "淡水").apply { age = 1 },
Bird("小鸟", true).apply { age = 2 },
Bird("企鹅", false).apply { age = 5 }
)
println("动物园信息:")
animals.forEach { animal ->
println(animal.getInfo())
animal.makeSound()
animal.move()
animal.eat("食物")
// 类型检查和转换
when (animal) {
is Dog -> animal.wagTail()
is Fish -> animal.swim()
is Bird -> animal.fly()
}
println()
}
}抽象类与接口的结合
kotlin
// 接口定义行为契约
interface Flyable {
val maxAltitude: Double
fun takeOff()
fun land()
fun fly(altitude: Double) {
if (altitude <= maxAltitude) {
println("飞行高度:${altitude}米")
} else {
println("超过最大飞行高度!")
}
}
}
interface Swimmable {
val maxDepth: Double
fun dive()
fun surface()
fun swim(depth: Double) {
if (depth <= maxDepth) {
println("游泳深度:${depth}米")
} else {
println("超过最大潜水深度!")
}
}
}
// 抽象类提供基础实现
abstract class Vehicle(val name: String, val maxSpeed: Double) {
var currentSpeed = 0.0
protected set
abstract val fuelType: String
abstract fun start()
abstract fun stop()
open fun accelerate(speed: Double) {
currentSpeed = minOf(currentSpeed + speed, maxSpeed)
println("$name 加速到 ${currentSpeed} km/h")
}
open fun brake(speed: Double) {
currentSpeed = maxOf(currentSpeed - speed, 0.0)
println("$name 减速到 ${currentSpeed} km/h")
}
}
// 飞机:既是交通工具又能飞行
class Airplane(name: String, maxSpeed: Double, override val maxAltitude: Double)
: Vehicle(name, maxSpeed), Flyable {
override val fuelType = "航空燃油"
private var isFlying = false
override fun start() {
println("$name 启动引擎")
}
override fun stop() {
println("$name 关闭引擎")
currentSpeed = 0.0
}
override fun takeOff() {
if (!isFlying) {
isFlying = true
println("$name 起飞")
}
}
override fun land() {
if (isFlying) {
isFlying = false
println("$name 降落")
}
}
}
// 潜艇:既是交通工具又能游泳
class Submarine(name: String, maxSpeed: Double, override val maxDepth: Double)
: Vehicle(name, maxSpeed), Swimmable {
override val fuelType = "核燃料"
private var isSubmerged = false
override fun start() {
println("$name 启动核反应堆")
}
override fun stop() {
println("$name 关闭核反应堆")
currentSpeed = 0.0
}
override fun dive() {
if (!isSubmerged) {
isSubmerged = true
println("$name 下潜")
}
}
override fun surface() {
if (isSubmerged) {
isSubmerged = false
println("$name 上浮")
}
}
}
// 水陆两栖车:能在陆地和水中行驶
class AmphibiousVehicle(name: String, maxSpeed: Double, override val maxDepth: Double)
: Vehicle(name, maxSpeed), Swimmable {
override val fuelType = "汽油"
override fun start() {
println("$name 启动发动机")
}
override fun stop() {
println("$name 关闭发动机")
currentSpeed = 0.0
}
override fun dive() {
println("$name 进入水中模式")
}
override fun surface() {
println("$name 回到陆地模式")
}
}
fun main() {
val vehicles = listOf(
Airplane("波音747", 900.0, 12000.0),
Submarine("核潜艇", 50.0, 500.0),
AmphibiousVehicle("水陆两栖车", 80.0, 10.0)
)
vehicles.forEach { vehicle ->
println("=== ${vehicle.name} ===")
println("燃料类型: ${vehicle.fuelType}")
println("最大速度: ${vehicle.maxSpeed} km/h")
vehicle.start()
vehicle.accelerate(50.0)
// 根据类型执行特定操作
when (vehicle) {
is Flyable -> {
vehicle.takeOff()
vehicle.fly(5000.0)
vehicle.land()
}
is Swimmable -> {
vehicle.dive()
vehicle.swim(20.0)
vehicle.surface()
}
}
vehicle.brake(30.0)
vehicle.stop()
println()
}
}实际应用示例
插件系统设计
kotlin
// 插件接口
interface Plugin {
val name: String
val version: String
val description: String
fun initialize(): Boolean
fun execute(context: PluginContext): PluginResult
fun cleanup()
// 默认实现
fun isCompatible(systemVersion: String): Boolean = true
}
// 插件上下文
data class PluginContext(
val parameters: Map<String, Any>,
val workingDirectory: String,
val logger: Logger
)
// 插件结果
sealed class PluginResult {
object Success : PluginResult()
data class Error(val message: String, val exception: Throwable? = null) : PluginResult()
data class Warning(val message: String) : PluginResult()
}
// 日志接口
interface Logger {
fun info(message: String)
fun warn(message: String)
fun error(message: String, exception: Throwable? = null)
}
// 抽象插件基类
abstract class BasePlugin(
override val name: String,
override val version: String,
override val description: String
) : Plugin {
protected var isInitialized = false
override fun initialize(): Boolean {
if (isInitialized) return true
return try {
onInitialize()
isInitialized = true
true
} catch (e: Exception) {
false
}
}
override fun cleanup() {
if (isInitialized) {
onCleanup()
isInitialized = false
}
}
protected abstract fun onInitialize()
protected abstract fun onCleanup()
protected fun validateContext(context: PluginContext, requiredParams: List<String>): Boolean {
return requiredParams.all { it in context.parameters }
}
}
// 具体插件实现
class FileProcessorPlugin : BasePlugin(
name = "文件处理器",
version = "1.0.0",
description = "处理文件的插件"
) {
override fun onInitialize() {
println("初始化文件处理器插件")
}
override fun onCleanup() {
println("清理文件处理器插件")
}
override fun execute(context: PluginContext): PluginResult {
if (!validateContext(context, listOf("inputFile", "outputFile"))) {
return PluginResult.Error("缺少必要参数:inputFile, outputFile")
}
val inputFile = context.parameters["inputFile"] as String
val outputFile = context.parameters["outputFile"] as String
context.logger.info("开始处理文件:$inputFile")
return try {
// 模拟文件处理
Thread.sleep(100)
context.logger.info("文件处理完成:$outputFile")
PluginResult.Success
} catch (e: Exception) {
context.logger.error("文件处理失败", e)
PluginResult.Error("文件处理失败:${e.message}", e)
}
}
}
class DataValidatorPlugin : BasePlugin(
name = "数据验证器",
version = "2.1.0",
description = "验证数据格式的插件"
) {
private val validationRules = mutableMapOf<String, (Any) -> Boolean>()
override fun onInitialize() {
println("初始化数据验证器插件")
// 添加默认验证规则
validationRules["email"] = { value ->
value is String && value.contains("@") && value.contains(".")
}
validationRules["phone"] = { value ->
value is String && value.matches(Regex("\\d{3}-\\d{3}-\\d{4}"))
}
}
override fun onCleanup() {
println("清理数据验证器插件")
validationRules.clear()
}
override fun execute(context: PluginContext): PluginResult {
if (!validateContext(context, listOf("data", "rules"))) {
return PluginResult.Error("缺少必要参数:data, rules")
}
@Suppress("UNCHECKED_CAST")
val data = context.parameters["data"] as Map<String, Any>
@Suppress("UNCHECKED_CAST")
val rules = context.parameters["rules"] as List<String>
val errors = mutableListOf<String>()
for (rule in rules) {
val validator = validationRules[rule]
if (validator == null) {
errors.add("未知验证规则:$rule")
continue
}
val value = data[rule]
if (value == null) {
errors.add("缺少字段:$rule")
} else if (!validator(value)) {
errors.add("字段验证失败:$rule")
}
}
return if (errors.isEmpty()) {
context.logger.info("数据验证通过")
PluginResult.Success
} else {
context.logger.warn("数据验证失败:${errors.joinToString(", ")}")
PluginResult.Warning("验证失败:${errors.joinToString(", ")}")
}
}
}
// 插件管理器
class PluginManager {
private val plugins = mutableMapOf<String, Plugin>()
private val logger = ConsoleLogger()
fun registerPlugin(plugin: Plugin): Boolean {
return if (plugin.initialize()) {
plugins[plugin.name] = plugin
logger.info("插件注册成功:${plugin.name} v${plugin.version}")
true
} else {
logger.error("插件初始化失败:${plugin.name}")
false
}
}
fun executePlugin(pluginName: String, context: PluginContext): PluginResult? {
val plugin = plugins[pluginName]
return if (plugin != null) {
logger.info("执行插件:$pluginName")
plugin.execute(context)
} else {
logger.error("插件未找到:$pluginName")
null
}
}
fun unregisterPlugin(pluginName: String) {
plugins[pluginName]?.let { plugin ->
plugin.cleanup()
plugins.remove(pluginName)
logger.info("插件卸载:$pluginName")
}
}
fun listPlugins(): List<Plugin> = plugins.values.toList()
}
// 控制台日志实现
class ConsoleLogger : Logger {
override fun info(message: String) {
println("[INFO] $message")
}
override fun warn(message: String) {
println("[WARN] $message")
}
override fun error(message: String, exception: Throwable?) {
println("[ERROR] $message")
exception?.printStackTrace()
}
}
fun main() {
val pluginManager = PluginManager()
val logger = ConsoleLogger()
// 注册插件
pluginManager.registerPlugin(FileProcessorPlugin())
pluginManager.registerPlugin(DataValidatorPlugin())
// 列出所有插件
println("已注册的插件:")
pluginManager.listPlugins().forEach { plugin ->
println("- ${plugin.name} v${plugin.version}: ${plugin.description}")
}
println()
// 执行文件处理插件
val fileContext = PluginContext(
parameters = mapOf(
"inputFile" to "input.txt",
"outputFile" to "output.txt"
),
workingDirectory = "/tmp",
logger = logger
)
val fileResult = pluginManager.executePlugin("文件处理器", fileContext)
println("文件处理结果:$fileResult")
println()
// 执行数据验证插件
val validationContext = PluginContext(
parameters = mapOf(
"data" to mapOf(
"email" to "user@example.com",
"phone" to "123-456-7890"
),
"rules" to listOf("email", "phone")
),
workingDirectory = "/tmp",
logger = logger
)
val validationResult = pluginManager.executePlugin("数据验证器", validationContext)
println("数据验证结果:$validationResult")
println()
// 卸载插件
pluginManager.unregisterPlugin("文件处理器")
pluginManager.unregisterPlugin("数据验证器")
}接口 vs 抽象类
选择指南
kotlin
// 使用接口的场景
interface Serializable {
fun serialize(): String
fun deserialize(data: String)
}
interface Comparable<T> {
fun compareTo(other: T): Int
}
// 使用抽象类的场景
abstract class DatabaseConnection(val connectionString: String) {
protected var isConnected = false
// 通用连接逻辑
fun connect(): Boolean {
if (isConnected) return true
return try {
doConnect()
isConnected = true
onConnected()
true
} catch (e: Exception) {
onConnectionError(e)
false
}
}
fun disconnect() {
if (isConnected) {
doDisconnect()
isConnected = false
onDisconnected()
}
}
// 子类必须实现的方法
protected abstract fun doConnect()
protected abstract fun doDisconnect()
// 可选的钩子方法
protected open fun onConnected() {}
protected open fun onDisconnected() {}
protected open fun onConnectionError(exception: Exception) {
println("连接错误:${exception.message}")
}
}
// 具体实现
class MySQLConnection(connectionString: String) : DatabaseConnection(connectionString) {
override fun doConnect() {
println("连接到MySQL数据库:$connectionString")
}
override fun doDisconnect() {
println("断开MySQL连接")
}
override fun onConnected() {
println("MySQL连接建立成功")
}
}
class PostgreSQLConnection(connectionString: String) : DatabaseConnection(connectionString) {
override fun doConnect() {
println("连接到PostgreSQL数据库:$connectionString")
}
override fun doDisconnect() {
println("断开PostgreSQL连接")
}
}最佳实践
1. 接口设计原则
kotlin
// 好的接口设计:单一职责
interface UserRepository {
fun findById(id: String): User?
fun save(user: User): User
fun delete(id: String): Boolean
}
interface UserValidator {
fun validate(user: User): ValidationResult
}
// 避免:接口过于庞大
interface BadUserService {
// 数据访问
fun findUser(id: String): User?
fun saveUser(user: User): User
// 验证
fun validateUser(user: User): Boolean
// 邮件发送
fun sendWelcomeEmail(user: User)
// 日志记录
fun logUserAction(action: String)
}2. 合理使用默认实现
kotlin
interface EventListener<T> {
fun onEvent(event: T)
// 提供默认的空实现
fun onError(error: Throwable) {
// 默认不处理错误
}
fun onComplete() {
// 默认不处理完成事件
}
}
// 使用者只需要实现关心的方法
class UserEventListener : EventListener<String> {
override fun onEvent(event: String) {
println("用户事件:$event")
}
// 不需要实现onError和onComplete
}3. 组合优于继承
kotlin
// 使用组合和接口而不是深层继承
interface Engine {
fun start()
fun stop()
val horsepower: Int
}
interface Transmission {
fun shiftGear(gear: Int)
val currentGear: Int
}
class Car(
private val engine: Engine,
private val transmission: Transmission
) {
fun start() {
engine.start()
}
fun drive() {
if (transmission.currentGear == 0) {
transmission.shiftGear(1)
}
println("汽车行驶中,引擎功率:${engine.horsepower}马力")
}
}下一步
掌握了接口和抽象类后,让我们学习Kotlin中的异常处理机制。
下一章: 异常处理
练习题
- 设计一个图形绘制系统,使用接口定义不同图形的行为
- 创建一个支付系统,支持多种支付方式(信用卡、支付宝、微信等)
- 实现一个消息队列系统,支持不同的消息处理策略
- 设计一个游戏角色系统,使用抽象类和接口实现不同职业和技能
- 创建一个数据访问层,支持多种数据库类型的操作