Java中,我们可以创建任意类的子类并重写任意方法,除非显式地的使用final关键字进行标注。但是我们修改基类的方法会导致子类方法报错,这就是脆弱的基类问题
。因为子类是继承父类的,所以我们可以根据业务需求改变子类,但是不能改变父类。
Java的类和方法默认是open
的,而Kotlin中默认都是final
的。
声明一个带open方法的open类
引用《Kotlin实战》当中的例子。
// 这个类是open的:其他可以继承它
open class RichButton : Clickable {
// 这个函数是final的:不能在子类中重写它
fun disable(){}
// 这个函数是open的:可以在子类当中重写
open fun animate(){}
// 这个函数重写了一个open函数并且它本身同样是open
override fun click() {}
}
interface Clickable {
fun click()
}
上面的例子我们可以知道,如果我们重写了一个基类或者接口的成员,重写了的成员同样是open的。如果你不想让子类重写你的实现,可以在显式的将重写的函数标注未final
。
open class RichButton : Clickable{
// 在这里的“final”并没有被删减是因为没有“final”的“override”是open的
final override fun click() {}
}
abstract关键字声明抽象类
Kotlin声明抽象类的关键字和Java一样也是abstract关键字。代码举例
// 抽象类:不能创建它的实例
abstract class Animated{
// 这个函数是抽象函数,没有实现必须在子类当中重写
abstract fun animate()
// 抽象类中的非抽象函数并不是默认open的,但是可以标准open
open fun stopAnimating(){}
fun animateTwice(){}
}
类访问修饰符的意义
修饰符 | 相关作用 | 标注 |
---|---|---|
final | 不能被重写 | 类中成员默认使用 |
open | 可以被重写 | 需要显式标明 |
abstract | 必须被重写 | 只能在抽象类使用:抽象成员不能实现 |
override | 重写父类或者接口中的成员 | 如果没有使用final表明,重写成员默认是open的 |
学习收获
这里知道了脆弱的基类问题
,学习到Koltin中的open、final和abstract修饰符以及它们的作用。我们可以利用修饰符解决脆弱的基类问题
。
希望我的博客对学习Kotlin开发的小伙伴有帮助。推广一下我微信公众号,我会经常更新一下技术干货或者开发踩坑历程,欢迎大家关注我!