kotlin 继承、接口和扩展

Java 中,所有的对象都默认继承 Object,里面有几个默认的方法可以供我们重写,常见的有 equals()、hashCode()、toString() 等方法;在 Kotlin 中,所有的对象默认继承 Any,

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

    public open fun hashCode(): Int

    public open fun toString(): String
}

它里面有三个方法可以供我们重写。Java 中的类,默认是可以继承的,而 Kotlin 中默认则是不能继承的,注意 open 这个关键字,有它修饰才可以继承,不管是类还是方法,或是属性值。

open class A {
    open fun a () { print("A") }

}

class B : A(){
    override fun a() {
        print("B")
    }
}

这里,继承使用 : 来表示,单独看这个看不出什么名堂,现在稍作调整

open class A1(name: String) {
    var name = name
    open fun a () { print("A") }
    constructor() : this("a1")
}

class B1 : A1{
    constructor() : super("b1")
    override fun a() {
        print("B1")
    }
}

在这个例子中,A1 的构造方法为包含一个参数的构造,这点写法和 Java 中不一样,并且直接在 class 后面添加括号的构造方法为主构造,如果没参数,可以写个空括号,或者省略括号,这样就默认为无参构造。A1 中的 constructor() 为辅助构造方法,它必须调用主构造方法,就如上面写的一样。B1 中继承了 A1,此时柱构造后面跟的是 A1 的空构造,子类必须在构造方法中调用父类的主构造方法,因此,在 B1 的里面就有了 constructor() : super("b1") ,上述可以简化为

class B2 : A1("b2"){
    override fun a() {
        print("B2")
    }
}

直接在 B2 的主构造后面跟随 A1 的主构造方法,我们再看看下面的一种情况

class B3 : A1{
    constructor(name: String) : super(name)
    constructor(name: String, age : Int) : this(name)
    override fun a() {
        print("B3")
    }
}

B3 中,内部的辅助构造方法,最终必须调用到父类的主构造方法,就如 B3 中的两个参数构造方法调用了一个参数的构造,一个参数的构造调用了父类的一个参数的构造方法。再比如一个实体类继承了一个抽象类和一个接口,抽象类和接口恰好有相同的抽象方法,在 java  中,子类只能重写一个,但在 kotlin 中,重写后还是可以调用父类的方法

open class AA {
    open fun ss () { println("A") }
    fun a() { println("a") }
}

interface BB {
    fun ss() { println("B") }
    fun b() { println("b") }
}

class CC : AA(), BB{
    override fun ss() {
        super<AA>.ss()//调用 AA.ss()
        super<BB>.ss()//调用 BB.ss()
    }
}

fun test(){
    val c =  CC()
    c.ss()
}

运行后,打印的值为

A
B


在java的 jdk 1.8 中,接口还是只能定义抽象方法和变量,不能定义可以重写的非抽象方法,但在 kotlin 中,不能定义常量,可以定义抽象和非抽象方法,举个例子

interface A {
    var name:String //name 属性, 抽象的
    fun start() { println("start A") }   // 已实现
    fun end()                  // 未实现
}

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

class C : A {
    override var name: String = "C" //重写属性
    override fun end() { println("end C") }   // 重写
}

class D : A, B {
    override var name: String = "D" //重写属性
    override fun start() {
        super<A>.start()
        super<B>.start()
    }

    override fun end() {
        super<B>.end()
        println(name)
    }
}

fun test1(){
    val d =  D()
    d.start()
    d.end()
}

打印结构为

start A
start B
end B
D


Kotlin 比着 Java 多了一个扩展函数的概念,什么意思呢?看个例子

class A{
    fun test(){
        println(" test  A ")
    }
}

fun A.too(){
    println(" too  A ")
}

fun function(){
    var a = A()
    a.test()
    a.too()
}

在这个例子中,定义了对象 A,A 中有个 test() 方法;上面的 A.too() 就是扩展的方法,它是个静态方法,优先于对象的存在;我们调用 function() 方法,打印数据如下

 test  A
 too  A


扩展的是静态的方法,但如果我们想直接调用,如下

class AA{
    fun test(){
        println(" test  AA ")
    }
    companion object
}

fun AA.too(){
    println(" too  AA ")
}

fun AA.Companion.to(){
    println(" to  AA ")
}

fun function(){
    var aa = AA()
    aa.test()
    aa.too()
    AA.to()
}

调用 function() 方法,打印数据为

 test  AA
 too  AA
 to  AA


 

发布了176 篇原创文章 · 获赞 11 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Deaht_Huimie/article/details/103532192