[kotlin]面向对象之接口、抽象类、伴生对象(Companion)

kotlin接口

开头我们介绍下kotlin的接口,kotlin接口跟java的接口差不多,jdk8中接口增加了默认方法实现,是为了兼容jdk向下兼容,还有考虑stream少写了很多代码,在kotlin中是否也可以写具体的方法,答案是肯定的。在多实现继承中有这样的问题,接口A有method方法的实现,父类B也有method方法实现,子类C怎么办,子类C**必须override相同的方法签名**,还有一个问题,怎样在子类C中指定调用A的实现,还有B的实现,这里kotlin也考虑的十分充分��

interface A {
    fun method() {
        println("A")
    }
}

open class B{
    open fun method(){
        println("B")
    }
}

/**
 * 接口,父类中都有方法实现,子类必须自己实现一套
 */
class C: A, B(){
    override fun method() {
        //语法太风骚
        super.method()
        super.method()
        println("C")
    }
}

fun main(args: Array) {
    var c = C()
    c.method()
}

kotlin抽象类

kotlin抽象类没什么好说的,只有一点,父类BaseClass中有method方法实现,子类ChildClass可以把父类的实现变成抽象方法

//抽象类
open class BaseClass{
    open fun method() {
    }
}

/**
 * 可以用abstract方法override父类
 */
abstract class ChildClass : BaseClass() {
    override abstract fun method()
}

kotlin伴生对象(Companion)

伴生对象的概念是什么,可以用java语言方式理解,它是静态内部类,为什么要设计这样的伴生对象?
首先我们了解对象声明的概念,java中没有提供直接对象,但是js中提供了对象,面向对象是靠对象来实现的,即使ts语法糖里有class关键字,但是本质还是对象,对象就可以不用实例化,直接调用。

//object declaration,对象声明
object MyObject {
    fun method() {
        println("method")
    }
}
fun main(args: Array) {
    MyObject.method()
}

下面来说明kotlin的伴生对象,下面的例子就是伴生对象的使用例子

class MyTest {
    companion object MyObject{
        var a: Int = 100

//        @JvmStatic
        fun method() {
            println("method invoked!")
        }
    }
}
fun main(args: Array) {
    MyTest.MyObject.method()

    println("------")
    println(MyTest.a)
    MyTest.method() //类似于静态方法,Kotlin中没有静态方法
    println("------")
    val v = MyTest.MyObject
    println(v.javaClass)
}

伴生对象是为了提供给kotlin像java一样,可以使用一个静态的使用方式,《effetive java》 中static是特别推荐用的,有很多好处,初始化的次数少,可以做缓存,推荐使用静态工厂方法来构造一个类的实例。

  • ��kotlin中,与Java不同的是, 类是没有static方法的
  • 在大多数情况下,kotlin推荐的做法是使用包级别的函数来作为静态方法,kotlin会将包级别的函数当做静态方法来看待
  • 如果不提供伴生对象的名字,那么编译器会提供一个默认的名字Companion,MyObject描述可以省略
  • ��虽然伴生对象的成员看起来像是Java中的静态成员,但在运行期,他们依旧是真实对象的实例成员(调用方式是kotlin的特定语法糖)
  • 在jvm上,可以降版式对象的成员真正成为类的静态方法与属性,他们通过@JvmStatic注解来实现
  • 伴生对象在编译后会生成一个静态的内部类
    针对上面的tips,我们使用java反编译kotlin的class文件,开看一看伴生对象本质是什么
    1.我们不使用@JvmStatic注解,执行javap MyTest.class

[kotlin]面向对象之接口、抽象类、伴生对象(Companion)_第1张图片
如上图看,根据我们调用方式虽然可以 使用MyTest.method(),但是MyTest反编译结果并没有method静态方法
2.我们加上@JvmStatic,然后重新build
[kotlin]面向对象之接口、抽象类、伴生对象(Companion)_第2张图片
如图就是对每条tips的最好的证明��

你可能感兴趣的:(koltin)