object是Kotlin中的关键字,在Java中没有。object主要有以下三种使用场景:
- 对象声明(Object Declaration)
- 伴生对象(Companion Object)
- 对象表达式(Object Expression)
1. 对象声明(Object Declaration)
(1)语法含义:将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式)
(2)基本示例
object RepositoryManager{
fun method(){
println("I'm in object declaration")
}
}
即将class关键字替换为object关键字,来声明一个类,与此同时也声明它的一个对象。只要编写这么多代码,这个类就已经是单例的了。
(3)使用
a. 在Kotlin中:
fun main(args: Array<String>) {
RepositoryManager.method()
}
像在Java中调用静态方法(在kotlin中没有静态方法)一样去调用其中定义的方法,但实际上是使用RepositoryManager类的单例对象去调用实例方法。
b. 在Java中:
public class JavaTest {
public static void main(String[] args) {
RepositoryManager.INSTANCE.method();
}
}
换句话说,object declaration的类最终被编译成:一个类拥有一个静态成员来持有对自己的引用,并且这个静态成员的名称为INSTANCE,当然这个INSTANCE是单例的,故这里可以这么去使用。
对于上面的代码如果用Java代码来表示的话相当于:
class RepositoryManager{
private RepositoryManager(){}
public static final RepositoryManager INSTANCE = new RepositoryManager();
}
(4) 注意点:
- 尽管和普通类的声明一样,可以包含属性、方法、初始化代码块以及可以继承其他类或者实现某个接口,但是它不能包含构造器(包括主构造器以及次级构造器)
- 它也可以定义在一个类的内部:
class ObjectOuter {
object Inner{
fun method(){
println("I'm in inner class")
}
}
}
fun main(args: Array<String>) {
ObjectOuter.Inner.method()
}
2. 伴生对象(Companion object)
在阐述伴生对象之前,首先我们要明确一点:在Kotlin中是没有static关键字的,也就是意味着没有了静态方法和静态成员。那么在kotlin中如果要想表示这种概念,取而代之的是包级别函数(package-level function)和我们这里提到的伴生对象。
class ObjectTest {
//MyObject可以省略
companion object MyObjec{
val a = 20
fun method() {
println("I'm in companion object")
}
}
}
a. 在Kotlin中:
fun main(args: Array<String>) {
//有两种调用方式
//方式一
ObjectTest.MyObject.method()
println(ObjectTest.MyObject.a)
//方式二(推荐方式)
ObjectTest.method()
println(ObjectTest.a)
}
a. 在Java中:
public class JavaTest {
public static void main(String[] args) {
ObjectTest.MyObject.method();
println(ObjectTest.MyObject.getA);
}
}
注:
- 在定义(定义时如果省略了伴生对象名,那么编译器会为其提供默认的名字Companion)和调用时伴生对象名是可以省略的。
- 一个类的伴生对象只能有一个。
3. 对象表达式(Object Expression)
(1)实现一个接口或类
interface AA {
fun a()
}
fun main(args: Array<String>) {
val aa = object : AA {
override fun a() {
println("a invoked")
}
}
aa.a()
}
(2) 不实现任何接口和类,并且在匿名内部类中添加方法
fun main(args: Array<String>) {
val obj = object {
fun a() {
println("a invoked")
}
}
obj.a() //打印:a invoked
}
(3) 实现多个接口和类
fun main(args: Array<String>) {
val cc = object : AA, BB() {
override fun a() {
}
override fun b() {
}
}
cc.a()
cc.b()
}