Kotlin学习笔记——属性和字段

声明属性

在类里面使用var或者val就可以声明了。

public class Address { 
  public var name: String = ...
  public var street: String = ...
  public var city: String = ...
  public var state: String? = ...
  public var zip: String = ...
}

只需要将成员变量定义成一个变量,默认是 public 的。编译器会自动生成 getter 和 setter 方法。所以上面的属性编译器默认添加了getter 和 setter 方法。

属性的使用

fun copyAddress(address: Address): Address {
  val result = Address() // there's no 'new' keyword in Kotlin
  result.name = address.name // accessors are called
  result.street = address.street
  // ...
  return result
}

上面对属性的访问,并不是像Java里面一样,直接访问属性的本身,而是默认调用了getter 和 setter 方法。

Getters and Setters

完整的属性声明如下:

var <propertyName>: <PropertyType> [= <property_initializer>]
  [<getter>]
  [<setter>]

其中initializer, getter 和 setter都是可选的。var是允许有getter 和 setter方法,如果变量是val声明的,它类似于Java中的final,所以如果以val声明就不允许有setter方法。

val isEmpty: Boolean
  get() = this.size == 0

var stringRepresentation: String
  get() = this.toString()
  set(value) {
    setDataFromString(value) // parses the string and assigns values to other properties
  }

下面举个例子:

class Person {
    var name: String = "abc"
    get() = field.toUpperCase()
    set(value){
        field = "Name: $value"
    }
}

fun main(args: Array<String>) {
    var customer: Person = Person()
    println(customer.name)   // ABC
    customer.name = "aaa"
    println(customer.name)   //NAME: AAA
}

对于属性,如果你想改变访问的可见性或者是对其进行注解,但是又不想改变它的默认实现,那么你就可以定义set和get但不进行实现。

var setterVisibility: String = "abc" // Initializer required, not a nullable type
  private set // the setter is private and has the default implementation

var setterWithAnnotation: Any?
  @Inject set // annotate the setter with Inject

Backing Fields

在上面例子中定义的Person类里面,属性的get和set方法里面使用了一个field,它是一个自动的返回字段,代表的就是属性。

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

field只有在访问的时候才会产生,其他时候是不会产生的。

Backing Properties

如果Backing Fields不适用的话,其实可以直接使用返回属性就可以了。

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")
  }

延迟初始化属性

对于非空类型的属性是必须初始化的。如果我们希望延迟进行初始化,就可以使用lateinit关键字了。

public class MyTest {
    lateinit var subject: TestSubject

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

    @Test fun test() {
        subject.method()  // dereference directly
    }
}

参考文章:Properties and Fields

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值