Kotlin中的类和对象的工作方式与大多数面向对象语言中的相同:通常,定义一个类,然后创建该类的多个实例:
import java.util.Random
class LuckDispatcher { //1
fun getNumber() { //2
var objRandom = Random()
println(objRandom.nextInt(90))
}
}
fun main() {
val d1 = LuckDispatcher() //3
val d2 = LuckDispatcher()
d1.getNumber() //4
d2.getNumber()
}
在Kotlin中,可以使用 object 关键字获取具有单一实现的数据类型。
单一 : 的含义类似于Java中单例模式,它确保即使多个线程尝试创建该类,也只创建该类的一个实例。
要在Kotlin中实现这一点,您只需要声明一个object :没类,没有构造函数,只有一个惰性实例。类似懒汉式单例,它将在访问对象时创建一次。
object 表达式
以下是对象表达式的基本典型用法:
- 要创建一个继承自某个(或某些)类型的匿名类的对象 通常使用以下方式
例如给Viewpager 添加PagerChangeListener
viewPager.addOnPageChangeListener(object :ViewPager.OnPageChangeListener{
override fun onPageScrollStateChanged(state: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onPageSelected(position: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
- 如果超类有一个构造函数,则必须传递适当的构造函数参数给它。 多个超类型可以由跟在冒号后面的逗号分隔的列表指定:
open class A(x: Int) {
public open val y: Int = x
}
interface B { …… }
val ab: A = object : A(1), B {
override val y = 15
}
- 对于一个简单的对象或属性结构。使用object 表达式后访问一个成员不需要再(创建一个对象,声明其成员并在一个函数中访问它)
fun rentPrice(standardDays: Int, festivityDays: Int, specialDays: Int): Unit { //1
val dayRates = object { //2
var standard: Int = 30 * standardDays
var festivity: Int = 50 * festivityDays
var special: Int = 100 * specialDays
}
val total = dayRates.standard + dayRates.festivity + dayRates.special //3
print("Total price: $$total") //4
}
fun main() {
rentPrice(10, 2, 1) //5
}
object 声明
它不是表达式,不能用于变量赋值。使用它来可以直接访问其成员函数 :
object DoAuth { //1 创建一个 objeDoAuth (object 声明)
fun takeParams(username: String, password: String){ //2 定义object 方法
println("input Auth parameters = $username:$password")
}
}
fun main(){
DoAuth.takeParams("foo", "qwerty") //3 直接使用声明调用其方法。 object 是在其这个时候创建的
}
Companion Objects
类中的对象声明定义了另一个有用的情况:伴生对象。从语法上讲,它类似于Java中的静态方法:使用类名作为限定符来调用对象成员。
class BigBen { //1 创建一个类
companion object Bonger { //2 定义一个名字为 Bonger (可以省略)伴生对象
fun getBongs(nTimes: Int) { //3 定义伴生对象方法
for (i in 1 .. nTimes) {
print("BONG ")
}
}
}
}
fun main() {
BigBen.getBongs(12) //4 使用类明直接调用伴生对象方法
}
即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员,而且,例如还可以实现接口:
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
val f: Factory<MyClass> = MyClass
对象表达式和对象声明之间的语义差异
对象表达式和对象声明之间有一个重要的语义差别:
-
对象表达式是在使用他们的地方立即执行(及初始化)的;
-
对象声明是在第一次被访问到时延迟初始化的;
-
伴生对象的初始化是在相应的类被加载(解析)时,与 Java 静态初始化器的语义相匹配。