对象表达式
通过对象表达式实现一个匿名内部类的对象用于方法的参数中:
window.addMouseListener(object:MouseAdapter(){
override fun mouseClicked(e:MouseEvent){ //...}
//...
})
对象可以继承于某个基类,或实现其他接口。
如果超类型有一个构造函数,则必须传递参数给它。
open class A(x:Int){
public open val y:Int=x
}
interface B{...}
val ab:A = object:A(1),B{
override val y = 15
}
请注意,匿名对象可以用作只在本地和私有作用域中声明的类型。如果你使用匿名对象作为公有函数的 返回类型或者用作公有属性的类型,那么该函数或属性的实际类型 会是匿名对象声明的超类型,如果你没有声明任何超类型,就会是 Any。在匿名对象 中添加的成员将无法访问。
class C{
//私有函数,所以其返回类型是匿名对象类型
private fun foo() = object{
val x:String = "x"
}
//公有函数,所以其返回类型是Any
fun publicFoo() = object{
val x:String = "x"
}
fun bar(){
val x1 = foo().x //正确
val x2 = publicFoo().x //错误:未能解析的引用“x”
}
}
对象声明
Kotlin使用object关键字来声明一个对象
object DataProviderManager{
fun registerDataProvider(provider:DataProvider){
//...
}
val allDataProviders:Collection<DataProvider>
get() = //...
}
//引用该对象,直接使用其名称即可
DataProviderManager.registerDataProvider(...)
//也可通过定义一个变量获取这个对象
//不同的变量对应同一个对象
var data1 = DataProviderManager
对象可以有超类型
object A:B(){ ...}
与对象表达式不同,当对象声明在另一个类的内部时,这个对象并不能通过外部类的实例访问到该对象,而只能通过类名来访问,同样该对象也不能直接访问到外部类的方法和变量。
class Site{
var name = "hello"
object DeskTop{
val url = "www.hello.com"
fun showName{
print("desk legs $name") //错误,不能访问到外部类的方法和变量
}
}
}
fun main(args:Array<String>){
var site = Site()
site.DeskTop.url //错误,不能通过外部类的实例访问到该对象
Site.DeskTop.url //正确
}
伴生对象
类内部的对象声明可以用 companion 关键字标记,这样它就与外部类关联在一起,我们就可以直接通过外部类访问到对象的内部元素。
class MyClass{
companion object Factory{
fun create():MyClass = MyClass()
}
}
val instance = MyClass.create() //访问到对象的内部元素
//可以省略掉该对象的对象名,使用Companion替代需要声明的对象名
class mClass{
companion object{
}
}
val x = mClass.Companion
一个类里面只能声明一个内部关联对象!!