对象声明
如下代码写法称为对象声明:
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
或者Named
:Machine.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
,定义的信息丢失了,失去了原本意义),实际用处不大。