#2 Уроки Kotlin. Введение: поля и переменные

Уроки Kotlin 2

В этом уроке мы узнаем о переменных в Kotlin, а также о некоторых особенностях языка.

Объявление переменных

Классы в 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 = ...
}

Для использования переменной мы просто пишем ее имя, также как в java:

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
}

Сеттеры и геттеры

Вот так выглядит полный синтаксис объявления переменных:

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

Инициализация сеттеров  геттеров является необязательной. Если переменная инициализируется сразу же, то писать тип переменной не обязательно:

var allByDefault: Int? // error: explicit initializer required, default getter and setter implied
var initialized = 1 // has type Int, default getter and setter

Между объявлением констант и объявлением переменных есть два различия:

  1. Вместо var пишется val
  2. Константа не имеет сеттера
val simple: Int? // has type Int, default getter, must be initialized in constructor
val inferredType = 1 // has type Int and a default getter

Мы можем написать свои сеттеры и геттеры как обычные методы прямо при объявлении переменной:

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
  }

По соглашению именем переменной в сеттере является value, но вы можете выбрать другое имя.

Если вам нужно изменить видимость сеттера или геттера, то вы можете просто написать имя метода (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

Late-Initialized переменные

Как правило, свойства объявленные как non-null должны быть инициализированы в конструкторе. Тем не менее, часто это бывает не удобно. Например, свойства могут быть инициализированы через Inject Depentions, или в setup-методе unit-теста. Чтобы решить эту проблему нужно отметить свойство модификатором lateinit:

public class MyTest {
    lateinit var subject: TestSubject

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

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

Модификатор может применяться только к var-переменным, которые объявлены в теле класса, а не в первичном конструкторе. Также тип поля должен быть ненулевым, а также не должен иметь примитивный тип.

При попытке доступа к lateinit-переменной до ее инициализации выбросится исключение, которое четко указывает на то, что переменная не была объявлена.

Комментарии:

2 комментария

  1. Novah Ответить

    В «Сеттеры и геттеры» ошыбка. Вместо ‘прямо’ написано ‘прzмо’.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *