前言
Kotlin基础object关键字。创建一个类做了轻微改动的类的对象,不用显式声明的子类。Kotlin用对象表达式和对象声明处理这种情况。
对象表达式
Java中匿名对象创建用new,Kotlin中创建一个匿名对象使用关键字object。
// java中
view.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){}
});
// kotlin中用object声明匿名类
view.setOnClickListener(object:View.OnClickListener{
override fun onClick(v:View?){}
})
父类使用open才能被继承
open class Person(name:String){}
open class Student(private val name:String):Person(name){}
val student = object :Student("xiake"){}
当仅仅需要一个对象,不需要特殊超类型
fun test() {
println("x:${point.x} y:${point.y}")
}
private val point = object {
val x =100
val y =100
}
匿名对象可用作本地和私有作用域中声明的类型。匿名对象作为共有函数的返回类型或共有属性类型,该函数或属性实际类型是匿名对象声明的超, 没有声明任何类型就是Any。在匿名对象中推荐加的成员将无法访问。
fun test() {
val x = point.x // 报错,无法访问x
}
// 共有属性point返回时一个Any类型
val point = object {
val x =100
val y =100
}
对象表达式中代码可以访问来自包含它的外部作用域的变量
class View{
private val name = "view"
private val point =object{
val x =100
val y = 100
val pName = name
}
}
对象声明
在object关键字上根一个名称。
object A{
const val TAG = "a"
fun getB(){
println("b")
}
}
对象声明不是表达式,不能用赋值句的右边。开发中常用object声明的对象式单例。点击Decompile反编译Java代码。使用object声明的对象反编译成Java也只是class类定义了私有的无参构造函数,该类的static中创建一个A对象,并给了变量INSTANCE。
A.INSTANCE.getB()
这些对象可以有自己的超类型
interface Info{
fun getInfo()
}
object A:Info{
override fun getInfo() {
}
}
对象声明不能在局部作用域(直接嵌套在函数内部),可以嵌套到其他对象声明或非内部类中
object A{
const val TAG="=A="
object B{
const val TAG="=B="
}
}
在声明的对象中嵌套声明B对象
class A{
object B{
const val TAG="=B="
}
}
类A中嵌套声明B对象
伴生对象
用companion关键字标记内部的对象声明
fun test() {
val tag = Person.TAG
// 外部类名访问伴生对象或方法
val instance = Person.newInstance()
}
class Person private constructor(){
companion object Factory{
const val TAG="factory"
fun newInstance() = Person()
}
}
通常省略伴生对象名称
fun test() {
val tag = Person.TAG
val instance = Person.newInstance()
}
class Person private constructor(){
companion object{
const val TAG="factory"
fun newInstance() = Person()
}
}
伴生对象默认名Companion
fun test() {
val tag = Person.Companion.TAG
val instance = Person.Companion.newInstance()
}
反编译成java,类内部定义了一个静态内部类Companion,该伴生兑现的默认类名。 用类Person内部声明的伴生对象实现了接口Factory
interface Factory<T>{
fun create():T
}
class Person{
companion object:Factory<Person>{
override fun create(): Person=Person()
}
}
对象表达式和对象声明差异
- 对象表达式在使用它们的地方立即初始化
- 对象声明式第一次被访问到时延迟初始化
- 伴生对象初始化在相应类被加载时,与Java静态初始化器的语义相匹配
总结
在Kotlin相关开发中object随处可见,要理解其中的含义,所有的开发语言都是相通的,大致原理之间有相互的联系。