Классы в Kotlin
Классы в Kotlin объявляются с помощью ключевого слова class:
class Invoice { /*...*/ }
Объявление класса состоит из имени класса, заголовка класса (с указанием его параметров типа, основного конструктора и т. д.) и тела класса, заключенного в фигурные скобки. И заголовок, и тело не являются обязательными; если у класса нет тела, фигурные скобки можно опустить.
class Empty
Конструкторы
Класс в Kotlin может иметь первичный конструктор и один или несколько вторичных конструкторов. Основной конструктор является частью заголовка класса: он идет после имени класса (и дополнительных параметров типа).
class Person constructor(firstName: String) { /*...*/ }
Если у основного конструктора нет аннотаций или модификаторов видимости, ключевое слово constructor можно опустить:
class Person(firstName: String) { /*...*/ }
Основной конструктор не может содержать никакого кода. Код инициализации может быть помещен в блоки инициализатора, которые имеют префикс с ключевым словом init.
Во время инициализации экземпляра блоки инициализатора выполняются в том же порядке, в каком они появляются в теле класса, чередующиеся с инициализаторами свойств:
class InitOrderDemo(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
Вывод:
First property: hello
First initializer block that prints hello
Second property: 5
Second initializer block that prints 5
Обратите внимание, что параметры первичного конструктора могут использоваться в блоках инициализатора. Их также можно использовать в инициализаторах свойств, объявленных в теле класса:
class Customer(name: String) {
val customerKey = name.toUpperCase()
}
Фактически, для объявления свойств и их инициализации из основного конструктора Kotlin имеет краткий синтаксис:
class Person(val firstName: String, val lastName: String, var age: Int) { /*...*/ }
Вы можете использовать конечную запятую при объявлении свойств класса:
class Person(
val firstName: String,
val lastName: String,
var age: Int, // конечная запятая
) { /*...*/ }
Во многом так же, как и обычные свойства, свойства, объявленные в основном конструкторе, могут быть изменяемыми (var) или доступными только для чтения (val).
Если у конструктора есть аннотации или модификаторы видимости, необходимо ключевое слово constructor, а перед ним идут модификаторы:
class Customer public @Inject constructor(name: String) { /*...*/ }
Вторичные конструкторы
Класс также может объявлять вторичные конструкторы с префиксом constructor:
class Person {
var children: MutableList<Person> = mutableListOf()
constructor(parent: Person) {
parent.children.add(this)
}
}
Если у класса есть первичный конструктор, каждый вторичный конструктор должен делегировать основному конструктору, прямо или косвенно, через другой вторичный конструктор(ы). Делегирование другому конструктору того же класса выполняется с помощью ключевого слова this:
class Person(val name: String) {
var children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
Обратите внимание, что код в блоках инициализатора фактически становится частью основного конструктора. Делегирование первичному конструктору происходит как первая инструкция вторичного конструктора, поэтому код во всех блоках инициализатора и инициализаторах свойств выполняется перед телом вторичного конструктора. Даже если у класса нет основного конструктора, делегирование по-прежнему происходит неявно, и блоки инициализатора по-прежнему выполняются:
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
Вывод:
Init block
Constructor
Если неабстрактный класс не объявляет никаких конструкторов (первичных или вторичных), у него будет сгенерированный первичный конструктор без аргументов. Видимость конструктора будет общедоступной (public). Если вы не хотите, чтобы у вашего класса был общедоступный конструктор, вам необходимо объявить пустой первичный конструктор с видимостью, отличной от видимости по умолчанию:
class DontCreateMe private constructor () { /*...*/ }
Примечание. В JVM, если все параметры основного конструктора имеют значения по умолчанию, компилятор сгенерирует дополнительный конструктор без параметров, который будет использовать значения по умолчанию. Это упрощает использование Kotlin с такими библиотеками, как Jackson или JPA, которые создают экземпляры классов с помощью конструкторов без параметров.
class Customer(val customerName: String = "")
Создание экземпляров классов
Чтобы создать экземпляр класса, мы вызываем конструктор, как если бы это была обычная функция:
val invoice = Invoice()
val customer = Customer("Joe Smith")
Обратите внимание, что в Kotlin нет ключевого слова new.
Члены класса
Классы могут содержать:
- Конструкторы и блоки инициализаторов
- Функции
- Свойства
- Вложенные и внутренние классы
- Объявления объекта
Читайте также:
Комментарии
Отправить комментарий