05. 子类和父类
2022年5月8日
05. 子类和父类
子类与父类的关系是,IS-A。 狼是一个动物,这是IS-A ,狼是子类,动物是父类。
1. 继承
继承是一种表示类与类关联关系的方式,使用继承要保证IS-A关系。
如下代码所示:
动物是犬科父类,犬科是狼的父类,子类拥有父类的特性(属性)和行为(方法)
open class Animal {
open var name: String = "没有名字的动物"
open fun makeNoise(make:String) {
println(name+"发出了"+make+"的叫声")
}
}
open class Canine : Animal() {
}
class Wolf : Canine() {
}
fun main(args: Array<String>) {
val wolf: Animal = Wolf()
wolf.makeNoise("嗷嗷嗷嗷呜~")
}
2. 覆写/复写/覆盖
在中文语义下,override被理解为覆盖在kotlin中更为准确
2.1 覆盖父类的属性与方法
狼类需要自己的名字和更加帅气的嚎叫
open class Animal {
open var name: String = ""
open fun makeNoise(make: String) {
println(name + "发出了" + make + "的叫声")
}
}
open class Canine : Animal() {
}
class Wolf : Canine() {
override var name = "一匹北方的狼"
override fun makeNoise(make: String) {
println(name + "发出了--独属于自己的帅气的" + make + "的叫声")
println("并且")
println(make+"又叫了一次")
}
}
fun main(args: Array<String>) {
val wolf: Animal = Wolf()
wolf.makeNoise("嗷嗷嗷嗷呜~")
}
使用override关键字, 覆写的方法按照由下向上查找。
2.2 不允许被覆盖
当父类被修饰final时,代表着它不可被覆盖
open class Canine : Animal() {
final override var name: String = "犬科"
final override fun makeNoise(make: String) {
println(name + "犬科" + make + "的叫声")
}
}
class Wolf : Canine() {
override var name = "一匹北方的狼" //提示错误
override fun makeNoise(make: String) { //提示错误
println(name + "发出了--独属于自己的帅气的" + make + "的叫声")
println("并且")
println(make + "又叫了一次")
}
}
2.3 父类的val变量可以被覆盖为var
当val向var转换时,增加了set方法。
父类的var如果被子类覆盖为val那么这是不合理的,这相当于告诉编译器,去掉set方法,这破坏了子类与父类的公共关系。
简单理解,一张小的纸是无法完全覆盖一张比它大的纸的。
问:如果子类可以将var覆盖为val,会发生什么?
答:可以想象,当子类对象指向父类时,父类调用set方法,但是子类中并不存在,这就会发生错误。