Kotlin汇总2-类构造,属性,字段

1.类构造函数

1.1 基础构造函数
class Person constructor(firstName: String) {
}

首选要清楚kotlin的默认修饰是public,所以上面的也可以简写成下面的

class Person(firstName: String) {
}

如果像把构造函数变成private

class Person private constructor(firstName: String) {
}

多个参数的构造函数

class Person private constructor(firstName: String, var b: String) {
}

给构造函数的参数指定默认值

class Person private constructor(firstName: String, var b: String = "bbbb") {
}

//调用如下
var p = Person("dave")
var p = Person("dave", "b")
1.2 第二级构造函数

只有第二级构造函数

class Child(){
    constructor(c: Child, a: String = "aaa") {

    }
}

当第二级构造函数和基础构造函数同时存在时,第二级构造函数必须代理基础构造函数

class Child(val a: String){
    constructor(c: Child, a: String = "aaa") : this(a){//使用this代理了基础构造函数

    }
}

另外需要注意,下面写法是错误的

class Child(){
    constructor(val c: Child, var a: String = "aaa") {
        //第二级构造函数的参数不能使用val或者var修饰
    }
}

2.属性

2.1 属性定义的完整语法
var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

属性必须被赋值或者使用get/set,比如几种情况

var a = "aaa"
var b = "bbb"
var c: String //因为var是可读可写属性,所以必须set/get都有
    set ...
    get ...
val d: String //因为val是只读属性,所以只需要get
    get ...
var f = "ffff"
    private set //因为f属性的set方法默认是public,显性声明private set之后,f属性的set方法就变成private了
2.2 延缓属性的初始化

因为属性必须初始化,但是有些时候有需要在特定情况下延迟它的初始化,可以使用lateinit关键字

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}
2.3 覆写属性
open class Foo {
    open val x: Int get { ... }
}

class Bar1 : Foo() {
    override val x: Int = ...//子类覆写了父类的属性x
}

需要注意可以用var覆写val,但是不能val覆写var

2.4 属性代理

通过by关键字

class Example {
    var p: String by Delegate() //by关键字代理属性
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name} in $thisRef.'")
    }
}

3. 反向字段和反向属性

3.1 反向字段

kotlin的类不支持字段,但是当使用自定义存储时又需要反向字段,这个时候可以用field关键字

var counter = 0 // the initializer value is written directly to the backing field
    set(value) {
        if (value >= 0) field = value
    }
3.2 反向属性

有些场景不适合使用反向字段,可以使用反向属相

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

上面这样写,只有table被调用到了,_table才会被创建。

4. 编译时常量

使用const关键字修饰,适用于如下场景
- Top-level or member of an object
- Initialized with a value of type String or a primitive type
- No custom getter

const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"

@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值