Kotlin中没有静态属性和静态方法 用object 修饰的类为单例(静态)类,里面的变量是静态的(private static,有相应get ,set 方法) 里面的方法 用 @JvmStatic 修饰的为静态的方法(public static),没有用@JvmStatic 修饰的不是静态的方法(public),但通过object修饰的静态类的实例也可以访问
用companion object 修饰的类为伴生对象,也是单例(静态)类(public static),伴生对象在类中只能存在一个 ,所以companion object 后面的类名可以省略。 里面的变量 会在companion object 所在类里面生成静态的成员 (private static,有相应get ,set 方法)同object。 里面的方法 用 @JvmStatic 修饰的为静态的(public static),会在companion object 所在类里面生成相对应的静态函数,没有用@JvmStatic 修饰的不是静态的(public),但通过object修饰的静态类的实例也可以访问
因此 object和companion object 修饰的类为单例(静态)类,里面的成员属性和成员函数可以当做静态属性和静态函数,已与直接访问。
抽象函数或者抽象类 默认就是open类型 除了抽象类和接口默认是可被继承外,其他类默认是不可以被继承的(相当于默认都带有final修饰符)。而类中的方法也是默认不可以被继承的。
如果你想要继承一个类,你需要使用open关键字修饰这个类。 如果你想要继承一个类的某个方法,这个方法也需要使用open关键字修饰。
3.1 替代运算操作符。使用方式是 operator 修饰一个方法,方法名为保留的操作符关键字,这样就可以让这个操作符的行为映射到这个方法,也叫操作符重载 注意 操作符仅可以定义为成员函数或扩展函数,所有的操作符都有一个预定义的英文单词以便用于重载操作符 如一元 +a 函数名必须是a.unaryPlus()
class Point constructor(var x:Int ,var y:Int){ operator fun plus(p: Point) { x += p.x y += p.y } } fun main(args: Array<String>) { val p1 = Point(8,10) val p2 = Point(2,3) val psum = p1 + p2 等同于 val psum = p1.plus(p2) }3.2 属性委托(代理)
class Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "${thisRef}, property '${property.name}' " } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("${thisRef} property '${property.name}' is setting value: '$value'") } } class DelegateProperties{ var property : String by Delegate() }DelegateProperties的property属性的getter/setter是分别委托给上面这个Delegate类的getValue和setValue方法。
定义如下一个函数
class Object(var name:String,var gender:String){ operator fun component1() = name }函数的名称一定是 component+数字 这时,如果调用了component1,那么得到的value就是name
为读/写属性返回一个属性委托,该属性在更改时 调用指定的回调函数进行判断,来决定回调是否更改 官网vetoable
var max: Int by Delegates.vetoable(0) { property, oldValue, newValue -> newValue > oldValue }max 初始值为1 ,当新值大于旧值时 才允许修改max的值
private lateinit var add: String val lazyValue: String by lazy { “HelloWorld” }
lzay 后跟表达式,表达式返回值必须和属性类型一致。第一次调用时开始执行 返回结果 ,后面再调用时,直接返回结果。(lambda表达式里面最后一行是返回结果,不需要return)lazy 操作符是线程安全的。如果不担心多线程问题或想提高更多的性能,可以使用 lazy(LazyThreadSafetyMode.NONE){ … }lateinit 则用于只能生命周期流程中进行获取或者初始化的变量,比如在 Android 的 onCreate() 中需要初始化的变量,lateinit修饰的变量未初始化前不能调用。
var name: String by Delegates.notNull()
参考 kotlin 常见 关键词 Kotlin lateinit 和 by lazy