Kotlin---扩展

介绍

除了与Java类比的这些功能之外,Kotlin还新增了一些新的概念

  • 数据类(data)
  • 扩展函数
  • 密封类(sealed)
  • 匿名类
  • 伴生对象(Companion)

数据类

通过data关键字来定义数据类。通常用来定义纯数据类型的结构体。定义的数据类只能有一个主构造函数定义该数据类中的变量。而在该类中,可以定义函数

data class Date(var year: Int = 10,
                var month: Int,
                var day: Int) {

    fun getDay(): String {
        return "year:$year...month:$month...day:$day"
    }
}

扩展函数

在Java中,如果有一个数据类需要转换成各种格式的结构,或者需要对属性做一些处理返回,通常会通过util或者wrappe来对数据结构做封装。而在Kotlin中提供了扩展函数可以来完成这一些操作。

我们可以在使用的类中,通过以下方式来定义类的扩展函数。但是该扩展函数的使用范围仅在这个类中使用。而该函数内有this指针,代表着调用该函数的对象,可以直接访问这个对象的成员

fun ClassName.Function():ReturnType{
     // TODO
}

例如:接上述代码,有一个类Date代表日期,在Child类中,代表生日,而在Product类中代表生产日期。那么就可以:

open class Child(name: String, age: Int = 18) : AbsPerson(name) {
    override var mAge = age
    
    fun childBirthDay(date: Date): String {
        return date.birthDay()
    }

    fun Date.birthDay(): String {
        return "Child BirthDay ${this.getDay()}...${this.year}"
    }
}

而在Product类中,可以直接通过Date.craeteDay来调用:

class Product {
    fun createDay(date: Date) {
        date.creatDay()
    }

    fun Date.creatDay() {
        this.getDay()
    }
}

通过扩展函数的方式来完成对与数据类以及其他类的隔离,保证各个类之间的隔离。同样,Kotlin也支持扩展属性,与函数类似定义。

密封类

密封类用来表示受限制的类继承结构。由于enum每一个实例都是一个常量,所以密封类被开发,密封类的子类可以有多个实例。

声明密封类后,也可以定义多个子类,但是这些子类都需要在与密封类同一个文件中。

// 声明SealedClass类
sealed class SealedClass
// 定义数据类继承自SealedClass
data class SealedDataClass(var data: Int) : SealedClass()
// 定义通用类继承自SealedClass
class SealedConstClass : SealedClass()

而它的用处最经典的是,在when子句中判断类型

fun choose(data: SealedClass) {
        when(data){
            is SealedConstClass -> data.hashCode()
            is SealedDataClass -> data.value
        }
}

匿名类

Java中可以通过new关键字创建匿名类,而Kotlin中则通过object关键字来定义匿名类。

通过函数返回的匿名对象必须是private声明的函数。否则无法解析。而匿名类也可以继承类:

class Teenager {

    fun runFast() {
        var round = object {
            var time: Long = 0
            var distance: Long = 0
        }
        round.time = 10
        round.distance = 100

        var round2 = runFast2()
        round2.distance = 100
        round2.time = 10
        round2.walk()

    }

    private fun runFast2() = object : Child("Bob") {
        var time: Long = 0
        var distance: Long = 0
    }
}

伴生对象(Companion)

用伴生对象声明的对象,与类没有什么关系,可以使用类名直接调用,例如在实现单例的时候可以直接使用。

class Teenager private constructor() {

    companion object Teen {
        var teenager: Teenager = Teenager()
    }

    fun runFast() {
        Log.e("Tag", "runFast")
    }
}

在使用的时候,可以直接访问并且调用

Teenager.teenager.runFast()

如果不使用companion修饰的话,则需要调用

Teenager.Teen.teenager.runFast()

可以理解成如果没有使用companion修饰的话,object只是声明了一个匿名类的对象,而对象名为Teen,然后通过这个对象访问teenager。如果使用companion的话,则可以直接访问teenager

你可能感兴趣的:(Kotlin---扩展)