Kotlin学习历程——对象声明与伴生对象

Kotlin语言中文站

对象声明

如下代码写法称为对象声明:

object UserInfoManager {
    //用户类型
    val userType : Int = 0
    
    //获取用户登录信息
    fun getLoginInfo() : String {
        return "用户登录信息"
    }
}

直观一点,我们转成java代码看看:

public final class UserInfoManager {
   private static final int userType;
   @NotNull
   public static final UserInfoManager INSTANCE;
    
   private UserInfoManager() {}

   static {
      UserInfoManager var0 = new UserInfoManager();
      INSTANCE = var0;
   } 
    
   @NotNull
   public final String getLoginInfo() {
      return "用户登录信息";
   }
}

单例模式(饿汉式)!这就简单明了了,类里面的属性和方法便可直接调用:

fun main(args: Array<String>) {
    UserInfoManager.userType
    UserInfoManager.getLoginInfo()
}

对象声明的语义我们可以理解为:定义一个类并且创建该类的单例。 我们需要注意的是:对象声明不能定义在函数内部,或者内部类中。


伴生对象

类内部的对象声明可以用companion关键字来标记,这种方法声明的对象叫类的伴生对象。

open class Machine {
    /** Machine类的伴生对象 */
    companion object {
        fun create() {}
    }
}

我们把kotlin代码转成Java代码看看:

public class Machine {
   public static final Machine.Companion Companion = new Machine.Companion((DefaultConstructorMarker)null);

   public static final class Companion {
      public final void create() {
      }

      private Companion() {
      }

      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

跟对象声明本质上差不多,都是定义一个类并且创建该类的单例。 伴生对象常见使用场景就是定义类变量或者类方法,因为在Kotlin中没有static关键字也就没法定义静态成员,而伴生对象就可以为我们解决这个问题:

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
    
    companion object {
        val openTag : Boolean = false

        fun open(context:Context){
            val it = Intent(context, SecondActivity::class.java)
            context.startActivity(it)
        }
    }
}

在其他activity中就可以直接调用:

SecondActivity.openTag
        
SecondActivity.open(this)

我们可以给伴生对象自定义名称,如果没有自定义名称默认将使用名称Companion, 如下是自定义名称Named

open class Machine {
    companion object Named{
        fun create() {}
    }
}

Java代码:

public class Machine {
   public static final Machine.Named Named = new Machine.Named((DefaultConstructorMarker)null);

   public static final class Named {
      public final void create() {
      }

      private Named() {
      }

      // $FF: synthetic method
      public Named(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

这里归纳一下:

  • 如果没有声明伴生对象的名称,默认使用名称Companion,调用伴生对象成员:Machine.Companion.create();
  • 如果声明了伴生对象名称,比如名称为Named,那么调用伴生对象成员:Machine.Named.create();

不过在实际使用中,可省略名称Companion或者NamedMachine.create();


对象表达式

创建一个匿名类的对象,就可以用对象表达式来实现。如下代码:

fun main(args: Array<String>) {
    //对象表达式
    val mListener = object : TestListener {
        override fun callback() {}
    }
    UserInfoManager.listener = mListener
}


//如果有多个超类,用逗号分隔便可:
fun main(args: Array<String>) {
    //多个超类
    val mListener = object : TestListener, IListener {
        override fun callback() {}
    }
    //赋值
    UserInfoManager.listener = mListener
}

android中最具代表性的代码就是按钮的点击事件监听了:

Button(context).setOnClickListener(object : View.OnClickListener{
    override fun onClick(v: View?) {
        //todo:click
    }
})

此外,有时候我们只是需要“一个对象而已”,并不需要特殊超类,我们可以简单地写:

val tempObject = object {
    val x : Int = 0
    val y : Int = 0
}
//可直接使用tempObject内部成员
println("tempObject : $tempObject.x - $tempObject.y")

不过这种写法也只能在声明处作用域使用,外面根本没法传递(传递的话是传递Any,定义的信息丢失了,失去了原本意义),实际用处不大。


上一篇:Kotlin学习历程——嵌套类与内部类
下一篇:Kotlin学习历程——函数与Lambda表达式(一)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hepingdev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值