class Books(var name: String, val page: Int) {
companion object ComBooks{
val a : Int = 10
fun doNote() {
println("do note")
}
}
}
fun main(args: Array<String>) {
Books.ComBooks.doNote()
println("Book.a = ${Books.ComBooks.a}")
println("-------------")
Books.doNote()
}
// Log
do note
Book.a = 10
-------------
do note
//伴随对象的成员可以通过类名做限定词直接使用:
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create()
//在使用了 companion 关键字时,伴随对象的名字可以省略:
class MyClass {
companion object {
}
}
//尽管伴随对象的成员很像其它语言中的静态成员,但在运行时它们任然是真正类的成员实例,比如可以实现接口:
interface Factory<T> {
fun create(): T
}
class MyClass {
companion object : Factory<MyClass> {
override fun create(): MyClass = MyClass()
}
}
//如果你在 JVM 上使用 @JvmStatic 注解,你可以有多个伴随对象生成为真实的静态方法和属性
2.属性字段相关
//使用field关键字
public var fieldProp = ""
get() = field
set(value) {
field = value;
}
//不生成:
val isEmpty: Boolean
get() = this.size == 0
//生成:
val Foo.bar = 1
3.延迟初始化属性
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method()
}
}
//这个修饰符只能够被用在类的 var 类型的可变属性定义中,不能用在构造方法中.并且属性不能有自定义的 getter 和 setter访问器.这个属性的类型必须是非空的,同样也不能为一个基本类型.在一个lateinit的属性初始化前访问他,会导致一个特定异常,告诉你访问的时候值还没有初始化
3.代理(委托)模式
interface Base {
fun print()
}
class BaseImpl(val x: Int) : Base {
override fun print() { printz(x) }
}
class Derived(b: Base) : Base by b
fun main() {
val b = BaseImpl(10)
Derived(b).print()
}
//在 Derived 的父类列表中的 by 从句会将 b 存储在 Derived 内部对象,并且编译器会生成 Base 的所有方法并转给 b
1.伴随(生)对象class Books(var name: String, val page: Int) { companion object ComBooks{ val a : Int = 10 fun doNote() { println("do note") } }}fun main(args:...