kotlin继承
1.子类构造器委托调用父类构造器
子类继承父类,子类构造器一定要直接或者间接委托调用调用父类构造器。
(1)子类有声明主构造器时
首先,子类次构造器一定要直接或者间接委托调用子类的主构造器;
其次,子类主构造器一定要委托调用父类构造器,从而子类次构造器能够通过主构造器间接委托调用父类构造器。
/**
* 父类
*/
open class Father {
//父类有一个带有形参的构造器
constructor(name: String?) {
}
}
/**
* 子类
*/
class Son(name: String?) : Father(name) {//子类继承于父类,同时子类主构造器委托调用父类构造器
constructor() : this(null) {//子类次构造器委托调用子类主构造器,间接委托调用父类构造器
}
constructor(name: String, age: Int) : this() {//子类次构造器委托调用子类其他次构造器,间接委托调用子类主构造器,从而间接委托调用父类构造器
}
}
(2)子类未声明主构造器(但是声明了次构造器)时
子类无主构造器时,次构造器不需要委托调用子类主构造器或者其他次构造器,但需要直接或间接委托调用父类构造器。
/**
* 父类
*/
open class Father {
//父类有一个带有形参的构造器
constructor(name: String?) {
}
//父类无参的次构造器
constructor() {
println("无参构造器")
}
}
/**
* 子类
*/
class Son : Father {
constructor(name: String?, age: Int) : super(name) {//子类次构造器直接委托调用父类构造器
}
constructor() : this(null, 0) {//子类次构造器委托调用其他次构造器,间接委托调用父类构造器
}
constructor(age: Int) {//子类次构造器未显式委托调用子类其他次构造器,也没显示委托调用父类构造器时,会默认委托调用父类无参的构造器
}
}
(3)子类未显式声明任何构造器时
子类未显式声明任何构造器时,系统会为子类自动生成一个无参的主构造器,因此继承时需要委托调用父类构造器。
/**
* 父类
*/
open class Father {
//父类有一个带有形参的构造器
constructor(name: String?) {
}
}
/**
* 子类
*/
class Son : Father(null)//声明时需为无参主构造器委托调用父类构造器
2.重写
(1)重写方法
重写方法遵循“两同、两小、一大”原则
-
两同:方法名相同、形参列表相同。
/** * 父类 */ open class Father { protected open fun method(a: String) { println("父类方法,传入参数:$a") } } /** * 子类 */ class Son : Father() { protected override fun method(a: String) { println("子类类方法,传入参数:$a") } }
-
两小:返回值类型比父类返回值类型小或相等、抛出异常类型比父类小或相等。
/** * 父类 */ open class Father { protected open fun method(a: String) : Any? { println("父类方法,传入参数:$a") return null } } /** * 子类 */ class Son : Father() { protected override fun method(a: String) : String?{ println("子类类方法,传入参数:$a") return "返回值" } }
-
一大:访问权限比父类大或相等
/** * 父类 */ open class Father { protected open fun method(a: String) : Any? { println("父类方法,传入参数:$a") return null } } /** * 子类 */ class Son : Father() { public override fun method(a: String) : String?{ println("子类类方法,传入参数:$a") return "返回值" } }
(2)重写属性
-
重写的子类属性的类型必须与分类属性类型兼容(变量类型)
/** * 父类 */ open class Father { open var a : Float = 1.1f } /** * 子类 */ class Son : Father() { override var a : Float = 2.2f }
-
子类属性访问权限必须大于等于父类类型
/** * 父类 */ open class Father { protected open var a : Float = 1.1f } /** * 子类 */ class Son : Father() { public override var a : Float = 2.2f }
-
只读属性(val)可被重写成读写属性(var),读写属性(var)不能被重写成只读属性(val)
/** * 父类 */ open class Father { protected open val a : Float = 1.1f } /** * 子类 */ class Son : Father() { public override var a : Float = 2.2f }
(3)强制重写
当子类同时继承多个超类(只能继承一个类,但可以实现多个接口)时,如果超类成员(属性/方法)名称一样时,子类需强制重写该成员。
子类想调用父类该成员,需通过super<父类名>.成员的方式调用。
/**
* 父接口
*/
interface FatherInterfs {
var a: Float
fun method() {
println("执行父接口里面该方法 a的值为:$a")//2.2
}
}
/**
* 父类
*/
open class Father {
protected open val a: Float = 1.1f
open fun method() {
println("执行父类该方法 $a")//2.2
}
}
/**
* 子类
*/
class Son : Father(), FatherInterfs {
override var a: Float = 2.2f
override fun method() {
super<FatherInterfs>.method()
super<Father>.method()
println("执行子类该方法 $a")//2.2
println("父接口a的值为 ${super<Father>.a}")//1.1
}
}