Kotlin的继承与重写
kotlin的继承
Kotlin中所有类都继承自Any类,Any类是所有类的超类,对于没有超类型声明的类是默认超类(Any 不是 java.lang.Object):
class LearnKotlin // 默认继承自Any
Any类默认提供三个函数
equals()
hashCode()
toString()
在kotlin中,除抽象类外的一个类可被继承要在class前添加open关键字进行修饰:
open class BaseClass(p: Int) // 定义基类
class ExtendsClass(p: Int) : BaseClass(p)
构造函数
1、子类有主构造函数
如果子类有主构造函数,则基类必须在主构造函数中立即初始化。示例如下:
open class Person(name : String, age : Int){
}
class Student(name : String, age : Int, var grade : String, var score : Int) : Person(name, age) {
}
2、子类无主构造函数
如果子类无主构造函数,则必须在每一个次构造函数中用 super 关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法。
class Student : Person {
constructor(ctx: Context) : super(ctx) {
}
constructor(ctx: Context, attrs: AttributeSet) : super(ctx,attrs) {
}
}
验证实例如下,先构造一个只有次构造函数的基类:
open class Person(name:String){
/**次级构造函数**/
constructor(name:String,age:Int):this(name){
//初始化
println("-------基类次级构造函数---------")
}
}
再构造一个继承基类的子类,同时修改子类的次构造函数:
class Student:Person {
constructor(name:String,age:Int,grade:String,score:Int):super(name, age){
println("姓名: ${name}")
println("年龄: ${age}")
println("年纪: ${grade}")
println("分数: ${score}")
}
}
实例化Student对象,即刻看到打印信息:
fun main(args: Array<String>) {
var student = Student("Jack", 18, "13", 89)
}
控制台打印信息如下:
重写
在基类里,使用fun声明函数时,默认此函数有final修饰,不能被子类重写。如果想要这个方法可以被重写覆盖,就需要用open字段修饰这方法,同时在重写的方法前必须使用override修饰。如果没有使用open修饰,则子类不允许命名相同名字的函数。
class NetConfig : Base() {
override fun draw() { // 前面声明override
super.draw()
}
}
open class Base {
open fun draw() {} //前面声明open
}
属性覆盖
和重写方法一样,需要重写的属性要用到open这个关键字,同时重写的属性需要用override来修饰。如果没有open来修饰属性,则子类不允许命名相同名字的属性:
open class Person{
open val num : Int = 0
}
class Student: Person() {
override var num = 10
}
这里要注意的是,你重写覆盖属性时,可以用一个var属性覆盖val属性,但反过来则不行。(一个val属性本质上是声明了一个get方法,而将其覆盖为 var 只是在子类中额外声明一个 set 方法,反之不行)。
当然,也可以直接在构造函数里覆盖属性:
open class Person{
open val num : Int = 0
}
class Student(override var num: Int = 0): Person() {
}
覆盖规则
在kotlin中,如果基类有多个相同的方法(继承或者实现自其他类,如A、B类),则必须要重写该方法,使用super范型去选择性地调用基类的实现:
open class A {
open fun f () { println("A") }
fun a() { println("a") }
}
interface B {
fun f() { println("B") } //接口的成员变量默认是 open 的
fun b() { println("b") }
}
class C() : A() , B{
override fun f() {
super<A>.f()//调用 A.f()
super<B>.f()//调用 B.f()
}
}
fun main(args: Array<String>) {
val c = C()
c.f()
}
对应命令控制台输出如下:
由程序中可见,C 继承自 A 或 B, C 不仅可以从 A 或者 B 中继承函数,而且 C 可以继承 A()、B() 中共有的函数。
End,如有问题请留言。