一、Object 表达式
创建匿名内部类的形式:object: ClassName {...}
// Handler 匿名表达式
val handler: Handler = object: Handler() {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
when(msg?.what) {
1 -> "Expression1"
2 -> "Expression2"
}
}
}
/*
* 方法中的匿名内部类的创建,当然这个点击事件在Anko中有更简单的写法;
* TextView(ctx).setOnClickListener {
* //...
* }
*/
TextView(ctx).setOnClickListener(object: View.OnClickListener{
override fun onClick(v: View?) {
//...
}
})
二、object 对象声明
2.1 直接声明 object 对象
在Java中,单例的声明可能具有多种方式:如懒汉式、饿汉式、静态内部类、枚举等;
在Kotlin中,单例模式的实现只需要一个object
关键字即可;
// Kt文件中的声明方式: object 关键字声明,其内部不允许声明构造方法
object SingleObject {
fun test() {
//...
}
}
// 调用方式:类名.方法名()
class Main {
fun test() {
SingleObject.test() //在class文件中,会自动编译成SingleObject.INSTANCE.test();调用方式
}
}
// ----------------源码和字节码分界线 ---------------
//Kotlin文件编译后的class代码如下:
public final class SingleObject {
public static final SingleObject INSTANCE;
public final void test() {
}
private SingleObject() {
INSTANCE = (SingleObject)this;
}
static {
new SingleObject();
}
}
2.2 继承自接口(抽象类)的对象声明
// Kt原文件代码
object MyMachine: Machine() {
override fun start() {
//...
}
}
abstract class Machine {
abstract fun start()
open fun stop() {}//只有被open修饰过的方法才能被继承,否则默认是final类型的,不可被重写;
}
// ----------------源码和字节码分界线 ---------------
// 以下是编译后裔的class文件
public final class MyMachine extends Machine {
public static final Single INSTANCE;
public void start() {
String var1 = "not implemented";
throw (Throwable)(new NotImplementedError("An operation is not implemented: " + var1));
}
private MyMachine() {
INSTANCE = (MyMachine)this;
}
static {
new MyMachine();
}
}
public abstract class Machine {
public abstract void start();
public void stop() {}
}
2.3 类内部的对象声明
class Single {
object Manage {//类内部的对象声明,没有被inner修饰的内部类都是静态的
fun execute() {
//...
}
}
}
// ----------------源码和字节码分界线 ---------------
public final class Single {
// 静态内部类
public static final class Manage {
public static final Single.Manage INSTANCE;
public final void execute() {}
private Manage() {
INSTANCE = (Single.Manage)this;
}
static {
new Single.Manage();
}
}
}
三、伴生对象 Companion Object
伴生对象是一个声明在类中的普通对象,它可以有名称 (默认为
Companion
) ,它可以实现一个接口或者有扩展函数或属性。
3.1 普通的伴生对象
class MyClass {
companion object Factory {
val url = ""
fun create(): MyClass = MyClass()
}
}
// 调用的时候,直接使用 类名.属性名 或 类名.方法名
MyClass.url
MyClass.create()
3.2 在伴生对象中实现接口
interface Factory<T> {
fun create(): T
}
class MyClass {
// 伴生类中实现接口
companion object : Factory<MyClass> {
val url = ""
// 实现接口的抽象方法
override fun create(): MyClass = MyClass()
}
}
// 调用
class Main {
fun test() {
setFactory(MyClass) // 这里传递进去的MyClass对象,其实就是MyClass的伴生对象
}
fun <T> setFactory(factory: Factory<T>) {
factory.create()
}
}
3.3 伴生对象的扩展
伴生对象的扩展和普通类的扩展一致
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
// 伴生类的扩展
fun MyClass.Factory.fun_name() = ...功能代码...
// 调用
MyClass.Factory.fun_name()