在Kotlin中,抽象类(abstract class)和接口(interface)用于声明抽象逻辑,但它们之间存在重要差异:
abstract class Animal(val name: String) { abstract fun makeSound() fun info() = println("我叫 $name") } interface Movable { fun move() } class Cat(name: String) : Animal(name), Movable { override fun makeSound() = println("喵") override fun move() = println("猫在移动") }
接口在Kotlin中可以包含状态(背后字段)吗?
大多数人回答说可以在接口中声明属性,但它们仍然没有背后字段——只有没有值存储的getter/setter。即使写get() = ...——值每次都会被计算。
示例:
interface MyInterface { val value: Int get() = 42 // 没有值存储,实时计算 }
故事
在一个大型项目中,高级开发人员试图在接口中存储状态(例如,计数器),期待属性var count: Int拥有背后字段。结果是所有实现该接口的类不得不以不同方式实现值的存储,导致不稳定的逻辑(如果忘记重写setter,数据就会丢失)。
故事
一位开发人员在需要多个行为策略实现的地方(策略模式)使用了抽象类。结果出现问题:层次结构中只有一个基本类,但对于不同的行为方面却需要组合。不得不将架构更改为接口。
故事
团队尝试同时继承两个抽象类(一个带逻辑,另一个带常用工具),在Kotlin中这是不可能的。问题在扩展应用程序时显现出来。这导致了显著的技术债务,因为类必须迅速进行重新组织。