伴生对象:companion
Kotlin语言中类不能有静态成员,像Java那样在类中用static关键字修饰的变量。
1、伴生对象
但是Kotlin提供了伴生对象,这个概念提供类似Java中通过类访问其中静态成员的语法。
1.1、定义
用companion关键字修饰在类中定义的对象。
class Master {
//Master类的伴生对象
companion object {
fun server() {}
}
}注意:每个类最多只能定义一个伴生对象

1.2、名称
①可以给伴生对象指定一个名称
class Master {
companion object servent {
fun server() {}
}
}伴生对象本质上还是生成一个同名的类,并且用“饿汉模式”将这个单例静态变量初始化:
public final class Master {
@NotNull
public static final servent servent = new servent((DefaultConstructorMarker)null);
public static final class servent {
private servent() {
}
public final void server() {
}
// $FF: synthetic method
public servent(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}②或者使用伴生对象的默认名称Companion,默认生成的类名就是Companion。
public final class Test {
@NotNull
public static final Companion Companion = new Companion((DefaultConstructorMarker)null);
public static final class Companion {
private Companion() {}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {this();}
}
}③伴生对象可以在声明的时候直接初始化,但必须是可继承的类型
open class Test{
}
class Master {
companion object servent : Test()
}其实也是生成一个类并且继承这个类,所以需要类型必须是可继承的:
public final class Master {
@NotNull
public static final servent servent = new servent((DefaultConstructorMarker)null);
public static final class servent extends Test {
private servent() {
}
// $FF: synthetic method
public servent(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}2、使用伴生对象
通过外部的类名可以直接访问伴生对象中的方法和属性,不需要显示的指明伴生对象的名称(因为每个类最多只有一个伴生对象,显然范围哪个伴生对象是确定的)。
2.1、访问伴生对象
在类的外部可以直接通过类名访问内部定义的伴生对象。
//通过类名直接访问伴生对象的属性,只能再Koltin代码之间
Master.server()
//或者通过伴生对象的名称间接访问。java代码访问kotlin必须要用Companion或指定的名称
Master.Companion.server()
//下面两句等效,持有内部伴生对象实例。
val tmp = Master.Companion
val tmp = Master2.2、伴生对象访问外部
Java中的static方法无法调用所在类的方法,同样Kotlin中类的伴生对象,也不可以访问类中的方法。但是访问private构造方法,所以伴生对象却可以调用,用来创建工厂模式的不二之选。
class Master private constructor() {
companion object {
fun server() {
val m = Master()
}
}
}2.3、伴生对象扩展
之前了解过Kotlin的扩展函数,可以定义类实例扩展的方法。伴生对象也是一个类的实例,能不能对其进行扩展呢?可以的,
class Master {
companion object
}在类外部定义类伴生对象的扩展函数
fun Master.Companion.server() {
println("server")
}其它地方可以调用伴生对象的扩展函数
Master.server()
Master.Companion.server()
