伴生对象:companion

QuibblerQuibbler 2020-11-11 约 7 分钟 1730 次阅读

伴生对象: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 = Master

2.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()

相关推荐

Parcelize:Parcelable 实现生成器
Kotlin

Parcelize:Parcelable 实现生成器

Parcelize:Parcelable 实现生成器Parcelable是安卓开发中常用的序列化方式,之前分享过一个Parcelable序列化插件,方便开发者快速生成代码,提高开发效率。1、Parcelize插件Kotlin官方也推出一个Parcelable自动生成的Gradle插件:Parcelize。1.1、引入插件在项目的build.gradle中添加:id("kotlin-parceliz

2.6k
Kotlin的继承
Kotlin

Kotlin的继承

Kotlin的继承1、超类:Any类似于Java中的Object类,Kotlin也有一个叫Any的超类,是所有类的父类,所有类都默认继承自该类。超类的定义如下,其中定义了三个函数:2、open注意上面的Any类用open修饰,表示该类可以被继承。Kotlin中的类默认都是final的,无法被继承:如果想让类可以被继承,就需要用在定义类的地方用open关键字标识该类可以被继承。3、构造器继承中涉及到

2.1k
 Kotlin基本语法
Kotlin

Kotlin基本语法

Kotlin基本语法了解Kotlin语言的基本语法。1、包kotlin文件以.kt结尾,编译文件还是如此只不过在文件名后面加上Kt后缀。这一点和Java不同,Java源文件.java,编译后为.class文件。1.1、包定义每个kotlin文件的第一行就用关键字package定义该文件所在的包。例:1.2、导包用到其它kotlin文件需要使用关键字import导入,这一点和Java一样。kotli

2.1k