1.子类构造器委托调用父类构造器 子类继承父类,子类构造器一定要直接或者间接委托调用调用父类构造器。 (1)子类有声明主构造器时 首先,子类次构造器一定要直接或者间接委托
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 } }