最近在 portal.kotlin-academy.com/#/ 上看到很多关于 Kotlin 的有趣的题目。个人觉得很适合 Kotlin 爱好者,感兴趣的小伙伴可自行查阅。
【有趣的 Kotlin 】系列记录自己对每一题的理解。
0x05:Making open abstract
open class A {
open fun a() {}
}
abstract class B: A() {
abstract override fun a()
}
open class C: B()
复制代码
以上代码,运行结果是什么?可选项:
- Compiles fine
- Error: Class ‘C’ is not abstract and does not implement abstract base class member
- Error: ‘a’ overrides nothing
- Error: Function ‘a’ must have a body
思考一下,记录下你心中的答案。
分析
Kotlin 中 open 关键字,用于类上,表示该类可以被继承,用于函数上,表示该函数可以被重写。 Java 中却无需如此,在 Java 中默认允许创建任意的子类并重写任意的方法,除非明确使用 final 关键字进行标注表示类不可继承、函数不可重写。而 Kotlin 中类默认是 final 不可继承的,类中的方法默认也是 final 不可重写的,于是 open 关键字应运而生。
Kotlin 中 abstract 关键字可以修饰类、函数和属性,分别表示抽象类、抽象函数和抽象属性。抽象函数在抽象类中不允许实现,抽象属性在抽象类中也不允许初始化。我们也不需要用 open 关键字来修饰抽象类、抽象函数以及抽象属性来告诉编译器它们可以被继承或者被重写,因为抽象的意义就在于被实现。

所以,题目中 A 和 B 两个类的写法是正确的。重点在于 C 类的写法:
abstract class B: A() {
abstract override fun a()
}
open class C: B()
复制代码
C 类继承抽象类 B ,且 C 类不是抽象类,所以 C 类必须实现 B 中的抽象函数 a(),但是题中未实现,所以按照我们的分析,题中代码会编译报错,且报错原因为类 C 未实现 B 类中的抽象方法 a()。因此,正确答案为:
选项2:Error: Class ‘C’ is not abstract and does not implement abstract base class member
知道原因,调整代码让其正确编译的方式也就很明显了,要么修改类 B ,干掉抽象函数或者重写函数 a() ,要么修改类 C,实现抽象函数或者将其改为抽象类。
方法一:
open class A {
open fun a() {}
}
abstract class B : A() {
}
open class C : B()
复制代码
方法二:
open class A {
open fun a() {}
}
abstract class B: A() {
abstract override fun a()
}
open class C: B() {
override fun a() {
println("a impl")
}
}
复制代码
方案三:
open class A {
open fun a() {}
}
abstract class B: A() {
abstract override fun a()
}
abstract class C: B()
复制代码
总结
- Kotlin 中类默认是
final不可继承的,函数和属性亦是如此; - 父类是抽象类,若子类是非抽象类,则必须实现父类中所有的抽象方法和抽象属性;若子类为抽象类,则没有这个必要;
- 抽象类、抽象函数和抽象类无需再用
open关键字修饰; open函数可以被抽象函数重写。



















![[02/27][官改] Simplicity@MIX2 ROM更新-一一网](https://www.proyy.com/wp-content/uploads/2020/02/3168457341.jpg)


![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)