kotlin 对象

2022-05-17  本文已影响0人  jxiang112

kotlin对象是很灵活的,常见的方式类似java一样new 一个类的实例对象,也可以通过匿名对象的方式创建对象,匿名对象的方式可以指定其父类或父接口,且可以同时一个父类或多个接口,这样可以达到——有时可能需要对某个类或者接口稍作临时小改动而不想通过创建子类继承的方式。

1、实例对象

实例对象是最简单也是最常用的方式,对现有的类创建一个实例对象:

class A {
}
val objA = A()

这种方式创建的对象可以对类的可访问成员进行访问,无任何限制

2、匿名对象

2.1、对象表达式

对象表达式的语法为:

object [[superClass()][,][superInterface][,superInterface]......] { 
[override list] 
}

对象表达式如果没有指定要继承的父类/父接口的情况下,其类型为Any类型,如果指定了父类则需要指定构造函数并传递所需的参数,在对象表达式实体{}中可以重写父类/父接口的成员。
对象表达式可以用作赋值语句、函数的参数、函数返回类型等
对象表达式作为赋值语句赋值给某个变量时,如果继承了一个类和多个接口,则需要显示指定成员变量的类型classType:

val tempObj: TObj2 = object : TObj2(21), TObj4 {
    override fun tFun() {
        println("x = ${super.x} and do do ")
    }

}

tempObj继承了TObj2、TObj4 ,需要显示指定其类型是TObj2或者TObj4
用对象表达时需要注意使用的场景:

例子如下:

open class TObj3 {
    val y = 30
}

class TObj {
    //私有变量,没有继承任何类,变量类型为匿名对象类型
    private val pObj = object  {
        val x = 1
    }
    
    //公有变量,没有继承任何类,变量类型为Any
    val pubObj = object {
        val x = 2
    }
    
    //公有函数,继承了TObj3,函数返回类型为TObj3
    fun pubFun() = object: TObj3(){
        val x = 3
    }

    fun main() {
        //私有变量类型为匿名对象,所以可以访问匿名对象的x
        println("private x = ${pObj.x}")
        //公有变量类型为Any,所以无法访问匿名对象的x
        println("public x = ${pubObj}")
        //公有函数,匿名对象继承了TObj3,所以函数返回的对象可以反问TObj3的y,但是不能反问匿名对象的x
        println("public fun = ${pubFun().y}")
    }
}

2.2、对象声明

语法:

object objectName [:superClass[,][superInterface]...] {
  [override list]
  [self params/funs]
}

对象声明的限制:

用法:对象声明的方式是线程安全,其属于单例声明,使用时直接使用对象名称.成员即可,如:

open class A1 {
    val x = 10
}
interface I1 {
    fun fun1()
}
object StaticObj : A1(), I1{
    override fun fun1() {
        println("x = ${super.x}")
    }
}

class ObjClient {
    fun main() {
        StaticObj.x
        StaticObj.fun1()
    }
}
2.2.1、伴生对象

在类内部的对象声明加上companion标记,表示此对象为伴生对象,语法为:

companion object [objName] [:[superClass][,][superInterface]....] {
  [override list]
  [params/funs]
}

在对象声明的前面加companion标记表示此对象为伴生对象。
伴生对象与对象声明有啥区别呢?

class A {
    companion object ObjA {
        val x = 123
    }
}

val value = A.x  // 等价于:A.ObjA.x

调用伴生对象的成员时,看起来跟java中的静态成员一样,但伴生对象的成员本质上不是静态成员,除非用@JvmStatic注解进行修饰,伴生对象的成员才会变成真正的静态成员,如:

class A {
    companion object ObjA {
        @JvmStatic
        val x = 123
    }
}

2.3、对象表达和对象声明的差异

上一篇下一篇

猜你喜欢

热点阅读