Kotlin语法(七)-属性和字段

时间:2023-02-06 15:43:03


1.     声明属性

         在类中,使用关键字var 或 val声明属性。

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

public classAddress {

  public var name: String = ...

  public var street: String = ...

  public var city: String = ...

  public var state: String? = ...

  public var zip: String = ...

}

 

2.     属性的使用

         要使用一个属性,只需要使用名称引用即可:

funcopyAddress(address: Address): Address {

  val result = Address() // there's no 'new'keyword in Kotlin

  result.name = address.name // accessors arecalled

  result.street = address.street

  // ...

  return result

}

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

3.     Getters and Setters

        完整的属性声明如下:

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

  [<getter>]

 [<setter>]

         初始器(initializer)、getter和setter都是可选的。 属性类型(PropertyType)如果可以从初始器或者父类中推导出来,也可以省略。

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

val isEmpty:Boolean

  get() = this.size == 0

 

varstringRepresentation: String

  get() = this.toString()

  set(value) {

    setDataFromString(value) // parses thestring and assigns values to other properties

  }

        实例:

class Person (name:String) {

    var name: String = name

        get() = field.toUpperCase()

        set(value) {

            field = value

        }

}

//

fun main(args:Array<String>) {

    var customer: Person = Person("xiaomin")

    println(customer.name)   // XIAOMIN

    customer.name = "lei"

    println(customer.name)   // LEI

}

 

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

var setterVisibility:String = "abc" // Initializer required, not a nullable type

  private set // the setter is private and hasthe default implementation

 

varsetterWithAnnotation: Any?

  @Injectset // annotate the setter with Inject

 

4.     支持(反向)域(Backing Fields)

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

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

var name: String =name

    get() = field.toUpperCase()

    set(value) {

        field = value

    }

 

5.     支持(反向)属性(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 areinferred

    return _table ?: throwAssertionError("Set to null by another thread")

  }

 

6.     延迟初始化属性

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

        lateinit只能在不可null的对象上使用,比须为var,不能为primitives(Int、Float之类)。

public class MyTest{

    lateinit var subject: TestSubject

 

    @SetUp fun setup() {

        subject = TestSubject()

    }

 

    @Test fun test() {

        subject.method()  // dereference directly

    }

}