Skip to content

接口和抽象类

概述

接口和抽象类是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中的异常处理机制。

下一章: 异常处理

练习题

  1. 设计一个图形绘制系统,使用接口定义不同图形的行为
  2. 创建一个支付系统,支持多种支付方式(信用卡、支付宝、微信等)
  3. 实现一个消息队列系统,支持不同的消息处理策略
  4. 设计一个游戏角色系统,使用抽象类和接口实现不同职业和技能
  5. 创建一个数据访问层,支持多种数据库类型的操作

本站内容仅供学习和研究使用。