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

来源:互联网 发布:路径动画导入unity3d 编辑:程序博客网 时间:2024/04/28 08:09

声明属性

在类里面使用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 == 0var 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 implementationvar 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>? = nullpublic 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
原创粉丝点击