在Scala中,你可以定义一个trait
和一个未定义的def
,并在实现类中实现。另外,def
可以实现为def
或val
。
trait Foo { def bar: Int }
class Baz(val bar: Int) extends Foo // ok
上下文
val
在Scala和Kotlin中具有相同的含义fun
和def
在Scala和Kotlin中或多或少相同trait
和interface
在Scala和Kotlin中或多或少是相同的。
这里的优点是trait的一些实现可以返回bar的静态值,该值在类初始化时设置,并且一些实现可以在每次访问bar时生成该值。
是否有类似的功能内置到Kotlin?
我已经累了实现fun
作为val
,这不起作用。我目前有下面的代码,但感觉这里有更多的锅炉板比必要的。
interface Foo {
fun bar(): Int
}
class Baz : Foo {
private val _bar: Int = TODO("Some heavy init function.")
override fun bar(): Int = _bar
}
可以用val
属性代替函数。当您定义一个只有=
而没有get()
的属性时,初始化代码将被调用一次并分配给后备变量,因此当访问该属性时,它只需读取存储在后备变量中的值,而无需再次计算它:
interface Foo {
val bar: Int
}
class Baz : Foo {
override val bar: Int = TODO("Some heavy init function.")
}
接口给了你灵活性,使它是按需计算(可能每次访问不同)使用自定义getter:
class Baz : Foo {
override val bar: Int get() = Random.nextInt(10)
}
或者使用属性委托惰性计算(第一次访问而不是在类实例化时):
class Baz : Foo {
override val bar: Int by lazy { TODO("Some heavy init function.") }
}
或者您可以将其升级为var
,并允许外部类覆盖属性中设置的内容:
class Baz : Foo {
override var bar: Int = 5
}
或者只在类内部:
class Baz : Foo {
override var bar: Int = 5
private set
}
使用自定义getter,您可以做一些更复杂的事情,包括支持属性,类似于使用fun
的代码。或者你可以设计你自己的属性委托,如果有一个你反复使用的模式。