Kotlin 继承和接口

一、Kotlin中类的继承

在Java中,类基于Object,而在Kotlin中类基于Any,所有类都默认继承Any。kotlin中的类默认是final类型的,不可被继承,想要作为基类被继承必须使用open关键字修饰。

对于没有超类型声明的类默认超类是Any,Any类只有三个函数~


package kotlin

public open class Any {
   
    public open operator fun equals(other: Any?): Boolean

    public open fun hashCode(): Int

    public open fun toString(): String
}

二、子类对构造函数的实现

1.当子类中有构造函数,则基类必须在主构造函数中立即初始化

open class S(name: String, age: Int) { //基类

}

//子类中有构造函数,则基类必须在主构造函数中立即初始化
class SS(var name: String, val age: Int, val score: Int) : S(name, age) {

}
fun main(args: Array<String>) {
    val s = SS("Tina", 20, 60)
    println("学生名:${s.name}")
    println("年龄:${s.age}")
    println("成绩:${s.score}")

}
学生名:Tina
年龄:20
成绩:60

2.当子类中没有主构造函数时,则必须每一个次要构造函数或代理另一个构造函数中用 super 关键字初始化基类。初始化基类时,可以使用super来调用基类的不同构造函数。

open class Personal(name: String) {
    constructor(name: String, age: Int) : this(name) {
        //初始化
        println("---基类次级构造函数-----")
    }
}

class SrudentImpl : Personal {
    constructor(name: String, age: Int, no: String, score: Int, likely: String) : super(name, age) {
        println("----- 继承类的次级构造函数 ------")
        println("学生名:${name}")
        println("年龄:${age}")
        println("学生号:${no}")
        println("成绩:${score}")
    }
}
fun main(args: Array<String>) {
    var student = SrudentImpl("Mikle", 18, "12485684", 98, "唱歌")
}
学生名:Mikle
年龄:18
学生号:12485684
成绩:98

3.方法的重写

基类中,使用fun声明函数时,该函数默认是final修饰的,不能被子类重写。如果允许该函数能被重写,则需手动添加open修饰它,子类复写使用override关键词。

open class D {
    open fun study() {  //允许子类重写的方法
        println("基类DD中定义需被子类重写的方法")
    }
}

class DD : D(), F {
    override fun study() {
        println("子类重写了父类的方法~~~")
        super<D>.study()
        super<F>.study()
    }
}

interface F {
    fun study() {  //允许子类重写的方法
        println("接口F中定义的方法~~")
    }
}

4.属性重写:使用override关键字

interface Foo {
    val count: Int
}

//属性的复写使用override关键字
class Bar1(override val count: Int) : Foo {}

class Bar2 : Foo {
    override var count: Int = 0
}

三、Kotlin中接口的实现

使用关键字interface定义接口,一个类可实现一个或多个接口

interface MyInterface {
    val name:String  //接口中的属性只能是抽象的,不允许初始化值,实现接口,必须重写属性
    fun bar()
    fun foo()
}

class Child: MyInterface {
    override var name:String="我是复写的name属性"  //重写属性
    override fun foo() {
        println("调用了foo方法")
    }

    override fun bar() {
       println("调用了bar方法")
    }
}

fun main(args: Array<String>) {
    val c = Child()
    c.foo()
    c.bar()
    println(c.name)
}
调用了foo方法
调用了bar方法
我是复写的name属性

***当实现多个接口时,可能会遇到同一方法继承多个实现的问题。

interface A {
    fun foo() {
        println("A")
    }  //有方法体,代表已经实现

    fun bar() //无方法体,是抽象的,未实现,需要被子类重写
}

interface B {
    fun foo() {
        println("B") //已实现
    }

    fun bar() {
        println("bar") //已实现
    }
}

class C : A {
    override fun bar() {
    }
}

class H : A, B {
    override fun bar() {
        super<B>.bar()
    }

    override fun foo() {
        super<A>.foo()
        super<B>.foo()
    }
}

fun main(args: Array<String>) {
   val h=H()
    h.foo()
    h.bar()
}
调用了foo方法
调用了bar方法
我是复写的name属性

猜你喜欢

转载自blog.csdn.net/qq_37982823/article/details/87920415