默认情况下,Kotlin中的所有类、方法和属性都是最终的(final)。也就是说,除非明确指定open修饰符,否则它们不能被继承或重写。
关键字open允许继承类或重写方法。这与Java的根本区别在于,Java中的类默认是开放用于继承的。
示例:
open class Animal { open fun sayHello() { println("Hello from Animal!") } } class Dog : Animal() { override fun sayHello() { println("Woof!") } }
Animal中去掉open,则尝试继承将导致编译错误。override是必需的。interface实现,不需要open。在Kotlin中可以像在Java中一样继承任何类吗?
答案: 不可以,只有被标记为open(或abstract)的类。普通类是最终的,不能被继承。这是为了提高代码的安全性和可预测性。
示例错误代码:
class Animal class Dog : Animal() // 编译错误:"Animal"是最终的
故事
在一个Android平台的项目中,一位年轻开发者试图从自定义View类继承用户组件,却忘记添加open。构建失败,原因不明显,导致进度延误。只有在仔细阅读编译器消息后,问题才被发现。
故事
在开发SDK时,规范要求一个可扩展的基类,但它被声明为没有open。交付给客户后发现,库不能在不更改源代码的情况下扩展。不得不发布更新。
故事
在一个项目中,旧的Java代码迁移到Kotlin时,忘记了类默认是封闭的。大部分使用mock的单元测试不再编译,延迟了发布过程。只有在大规模添加open后,问题才得到解决。