English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В этой статье вы узнаете о конструкторах в Kotlin (главный конструктор и дополнительный конструктор) и блоках инициализации с помощью примеров.
Конструктор - это простой способ инициализации свойств класса.
Это специальная функция члена, которая вызывается при инстанцировании (создании) объекта. Но они работают немного по-разному в Kotlin.
В Kotlin есть два конструктора:
Главный конструктор - Простой способ инициализации класса
Второй конструктор - Позволяет вам разместить другую логику инициализации
Главный конструктор является частью заголовка класса. Вот пример:
class Person(val firstName: String, var age: Int) { // тело класса }
Код, заключенный в скобки, это главный конструктор: (val firstName: String, var age: Int).
Конструктор объявляет два свойства: firstName (чтение только, так как оно объявлено с помощью ключевого слова val) и age (чтение и запись, так как оно объявлено с помощью ключевого слова var).
fun main(args: Array<String>) { val person1 = Person("Joe", 25) println("First Name = ${person1.firstName}") println("Age = ${person1.age}") } class Person(val firstName: String, var age: Int) { }
При выполнении этого программы, вывод будет:
Имя = Joe Возраст = 25
При создании объекта класса Person передается значение Joe и 25, как будто Person - это функция.
Это инициализирует свойства firstName и age объекта person1 соответственно как "Joe" и 25.
Есть и другие методы использования главного конструктора.
Синтаксис главного конструктора ограничен и не может содержать никакого кода.
Для размещения инициализационного кода (не только кода инициализации свойств) используется блок инициализации. Он начинается с ключевого слова init . Давайте изменим пример с помощью блока инициализации:
fun main(args: Array<String>) { val person1 = Person("joe", 25) } class Person(fName: String, personAge: Int) { val firstName: String var age: Int // блок инициализации init { firstName = fName.capitalize() age = personAge println("Имя = $firstName") println("Возраст = $age") } }
При выполнении этого программы, вывод будет:
Имя = Joe Возраст = 25
Здесь, при создании объекта person1, в круглых скобках перед параметрами fName и personAge соответственно передаются значения "Joe" и 25. Однако, при использовании fName и personAge не используется var или val, и они не являются свойствами класса Person.
Класс Person объявляет два свойства firstName и age.
Когда объект person1 создается, выполняется код внутри блока инициализации. Блок инициализации не только инициализирует его свойства, но и выводит их.
Это другой способ выполнения той же задачи:
fun main(args: Array<String>) { val person1 = Person("joe", 25) } class Person(fName: String, personAge: Int) { val firstName = fName.capitalize() var age = personAge // блок инициализации init { println("Имя = $firstName") println("Возраст = $age") } }
Чтобы отличить параметры конструктора от свойств, используются различные имена (fName и FirstName, а также Personage и age). Для параметров конструктора наиболее часто используется _firstName и _age, а не совершенно иные имена. Например:
class Person(_firstName: String, _age: Int) { val firstName = _firstName.capitalize() var age = _age // блок инициализации init { ... .. ... } }
Вы можете предоставить значения по умолчанию для параметров конструктора (аналогично предоставлениюЗначения по умолчаниюПример:
fun main(args: Array<String>) { println("person1 был инстанцирован") val person1 = Person("joe", 25) println("person2 был инстанцирован") val person2 = Person("Jack") println("person3 был инстанцирован") val person3 = Person() } class Person(_firstName: String = "UNKNOWN", _age: Int = 0) { val firstName = _firstName.capitalize() var age = _age // блок инициализации init { println("Имя = $firstName") println("Возраст = $age\n") } }
При выполнении этого программы, вывод будет:
Имя = Joe Возраст = 25 person2 был инстанцирован First Name = Jack Age = 0 person3 был инстанцирован First Name = UNKNOWN Age = 0
В Kotlin класс может также содержать один или несколько второстепенных constructorов. Они создаются с помощью ключевого слова constructor.
Второстепенные constructorа в Kotlin не так часто встречаются. Самый распространенный случай использования второстепенных constructorа — это когда вам нужно расширить класс, предоставляющий несколько constructorов для инициализации класса по-разному. Перед изучением убедитесь, что вы уже знаетеИнherit в Kotlin.
Вы можете создать метод второстепенного constructorа в Kotlin следующим образом:
class Log { constructor(data: String) { // Некоторый код } constructor(data: String, numberOfData: Int) { // Некоторый код } }
Здесь класс Log имеет два второстепенных constructorа, но нет главного constructorа.
Вы можете расширить класс следующим образом:
class Log { constructor(data: String) { // Код } constructor(data: String, numberOfData: Int) { // Код } } class AuthLog: Log { constructor(data: String): super(data) { // Код } constructor(data: String, numberOfData: Int): super(data, numberOfData) { // Код } }
Здесь constructor класса производного AuthLog вызывает соответствующий constructor класса базового Log. Для этого используется super().
В Kotlin вы также можете использовать this() для вызова другого constructor из того же класса (как в Java).
class AuthLog: Log { constructor(data: String): this(data, 10) { // Код } constructor(data: String, numberOfData: Int): super(data, numberOfData) { // Код } }
fun main(args: Array<String>) { val p1 = AuthLog("Bad Password") } open class Log { var data: String = "" var numberOfData = 0 constructor(_data: String) { } constructor(_data: String, _numberOfData: Int) { data = _data numberOfData = _numberOfData println("$data: $numberOfData times") } } class AuthLog: Log { constructor(_data: String): this("From AuthLog -> " + _data, 10) { } constructor(_data: String, _numberOfData: Int): super(_data, _numberOfData) { } }
При выполнении этого программы, вывод будет:
From AuthLog -> Bad Password: 10 times
Примечание:Если класс не имеет главного конструктора, то вторичный конструктор должен инициализировать базовый класс или делегат другим конструктором (как показано в примере выше).