一,对象表达式
创建匿名内部类的形式: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?) {
//...
}
})
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
二,对象声明
2.1直接声明对象对象
在Java的中,单例的声明可能具有多种方式:如懒汉式,饿汉式,静态内部类,枚举等;
在科特林中,例单模式的实现只需要一个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();
}
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 三十
- 31
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() {}
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 三十
- 31
- 32
- 33
- 34
- 35
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();
}
}
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
三,伴生对象Companion Object
伴生对象是一个声明在类中的普通对象,它可以有名称(默认为
Companion
),它可以实现一个接口或者有扩展函数或属性。
3.1普通的伴生对象
class MyClass {
companion object Factory {
val url = ""
fun create(): MyClass = MyClass()
}
}
// 调用的时候,直接使用 类名.属性名 或 类名.方法名
MyClass.url
MyClass.create()
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
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()
}
}
- 1
- 2
- 3
- 4
- 五
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
3.3伴生对象的扩展
伴生对象的扩展和普通类的扩展一致
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
// 伴生类的扩展
fun MyClass.Factory.fun_name() = ...功能代码...
// 调用
MyClass.Factory.fun_name()