先画靶后射箭
不像人家C艹可以一个类继承好多个类,Kotlin继承了它爹的单继承,于是一个类只能继承一个类了。但有其父必有其子,Kotlin把Java的接口(interface) 也一起继承了过来
[!NOTE] 在Kotlin里边,若要使一个非抽象类可以被继承,需要在前面加上一个
open
关键字,不然无法继承。对于类里面的方法,若是没有open
关键字也是无法重写的但是接口则不一样,接口里面的方法默认就是拿来重写的,加上
open
只会无事发生,不过如果接口里的方法在一个类中重写了,那这个方法如果想在下一个被继承的类里边重写那还是得加上open
接口是干啥的
接口里面可以塞一堆等待实现的(或已经实现的)方法
比如这有一个用来Study
的接口
interface Study {
val nowTime: Long
fun readBooks()
fun doNothing()
fun doHomeWork() {
println("Doing homework is good for your health.")
}
fun studyTime() {
println("Studying at $nowTime")
}
}
在这一堆方法中,上面那两个没有 {}
的叫抽象方法,因为它们不像下面那两个给出了默认的具体实现,看着就很抽象
而那个nowTime
则是一个抽象属性
这些抽象的东西,都是继承的类必须要实现的,除非这个类也是一个抽象(抽象类
把抽象变具象的关键词便是重写(override) ,这在每个继承的类里面实现
咋继承重写
先来一个开放类吧
open class Person(val name: String, val age: Int) {
var height: Int = 0
fun eat() {
println("$name is eating. He is $age years old. His height is $height cm")
}
open fun sleep() {
println("$name is sleeping.")
}
}
这个开放类open
了,所以可以被继承,sleep()
方法也open
了,所以可以重写
再来一个类来继承吧
open class Student(val no: String, val grade: Int, name: String, age: Int) :
Person(name, age), Study {
// 覆盖接口的抽象方法
override fun readBooks() {
println("$name is reading books.")
}
override fun doNothing() {
println("$name, grade $grade, number $no, is doing nothing.")
}
override val nowTime: Long // 如果不赋值绘编译失败哦
get() = System.currentTimeMillis()
// 有默认实现的方法也可以重写!
override fun sleep() {
println("$name is sleeping, but still thinking about his homework!")
}
}
继承的语法简直就像C艹一样,加个逗号就能继承多个了
这下终于明白Activity里边的override
是咋来的了
既可推倒重来,又可继往开来
如果再来一个类来继承上面的类
class SeniorStudent(no: String, grade: Int, name: String, age: Int) :
Student(no, grade, name, age) {
override fun readBooks() {
super.readBooks()
println("But also solving difficult problems!")
}
override fun doNothing() {
super.doNothing()
println("$name is spending time with friends, but secretly studying!")
}
}
现在终于可以明白这super
的意思了,当然不是超级,而是继承这个方法的父类实现
也就相当于把原本的代码copy过来,然后还能在此基础上添加你想要的
最后的最后
自此,一锤定音
尘埃,已然落定