В тази статия ще научите за конструктори в Kotlin (както първични, така и вторични конструктори), както и блокове за инициализация с помощта на примери.
Конструкторът е кратък начин за инициализиране на свойствата на класа.
Това е специална функция член, която се извиква, когато обект е създаден (създаден). Начинът на работа в Котлин обаче е малко по-различен.
В Kotlin има два конструктора:
- Първичен конструктор - кратък начин за инициализиране на клас
- Вторичен конструктор - позволява ви да поставите допълнителна логика за инициализация
Първичен конструктор
Първичният конструктор е част от заглавката на класа. Ето пример:
class Person (val firstName: String, var age: Int) (// тяло на класа)
Блокирането на код, заобиколен от скоби е основният конструктор: (val firstName: String, var age: Int)
.
Конструкторът декларира две свойства: firstName
(свойство само за четене, както е декларирано с ключова дума val
) и age
(свойство четене-запис, както е декларирано с ключова дума var
).
Пример: Основен конструктор
fun main(args: Array) ( val person1 = Person("Joe", 25) println("First Name = $(person1.firstName)") println("Age = $(person1.age)") ) class Person(val firstName: String, var age: Int) ( )
Когато стартирате програмата, изходът ще бъде:
Име = Joe Age = 25
Когато обектът на Person
класа е създаден "Joe"
и 25
стойностите се предават, сякаш Person
е функция.
Това инициализира firstName
и age
свойства на person1 обект към "Joe"
и 25
съответно.
Има и други начини за използване на първични конструктори.
Основни блокове на конструктора и инициализатора
Първичният конструктор има ограничен синтаксис и не може да съдържа никакъв код.
За да се постави инициализиращият код (не само кодът за инициализиране на свойствата), се използва блок за инициализация. Той има префикс с init
ключова дума. Нека модифицираме горния пример с блок за инициализация:
fun main(args: Array) ( val person1 = Person("joe", 25) ) class Person(fName: String, personAge: Int) ( val firstName: String var age: Int // initializer block init ( firstName = fName.capitalize() age = personAge println("First Name = $firstName") println("Age = $age") ) )
Когато стартирате програмата, изходът ще бъде:
First Name = Joe Age = 25
Тук параметрите fName и personAge вътре в скобата приемат стойности "Joe"
и 25
съответно когато е създаден обект person1. Въпреки това, fName и personAge се използват, без да се използва var
или val
, и не са свойства на Person
класа.
В Person
класа има две свойства FirstName и възраст са обявени.
Когато person1
обектът е създаден, кодът в блока на инициализатора се изпълнява. Блокът инициализатор не само инициализира свойствата си, но и ги отпечатва.
Ето друг начин за изпълнение на същата задача:
fun main(args: Array) ( val person1 = Person("joe", 25) ) class Person(fName: String, personAge: Int) ( val firstName = fName.capitalize() var age = personAge // initializer block init ( println("First Name = $firstName") println("Age = $age") ) )
За да се разграничат параметърът на конструктора и свойството, се използват различни имена (fName и firstName, и personAge и възраст). По-често се използва _firstName и _age вместо напълно различно име за параметрите на конструктора. Например:
клас Person (_firstName: String, _age: Int) (val firstName = _firstName.capitalize () var age = _age // инициализиращ блок init (…))
Стойност по подразбиране в първичен конструктор
Можете да предоставите стойност по подразбиране на параметрите на конструктора (подобно на предоставянето на аргументи по подразбиране на функциите). Например:
fun main(args: Array) ( println("person1 is instantiated") val person1 = Person("joe", 25) println("person2 is instantiated") val person2 = Person("Jack") println("person3 is instantiated") val person3 = Person() ) class Person(_firstName: String = "UNKNOWN", _age: Int = 0) ( val firstName = _firstName.capitalize() var age = _age // initializer block init ( println("First Name = $firstName") println("Age = $age") ) )
Когато стартирате програмата, изходът ще бъде:
Име = Joe Age = 25 лице2 е създадено Име = Jack Age = 0 person3 е създадено Име = UNKNOWN Age = 0
Котлин Вторичен конструктор
В Kotlin клас може също да съдържа един или повече вторични конструктори. Те са създадени с помощта на constructor
ключова дума.
Вторичните конструктори не са толкова често срещани в Kotlin. Най-често се използва вторичен конструктор, когато трябва да разширите клас, който предоставя множество конструктори, които инициализират класа по различни начини. Не забравяйте да проверите наследството на Kotlin, преди да го научите.
Ето как можете да създадете вторичен конструктор в Kotlin:
class Log (constructor (data: String) (// some code) конструктор (data: String, numberOfData: Int) (// some code))
Тук Log
класът има два вторични конструктора, но няма първичен конструктор.
Можете да разширите класа като:
class Log (constructor (data: String) (// code) constructor (data: String, numberOfData: Int) (// code)) class AuthLog: Log (constructor (data: String): super (data) (// code ) конструктор (data: String, numberOfData: Int): super (data, numberOfData) (// код))
Тук конструкторите на производния клас AuthLog
извикват съответния конструктор на базовия клас Log
. За това super()
се използва.
В Kotlin можете също да извикате конструктор от друг конструктор от същия клас (като в Java), използвайки this()
.
class AuthLog: Log (constructor (data: String): this (data, 10) (// code) constructor (data: String, numberOfData: Int): super (data, numberOfData) (// code))
Пример: Вторичен конструктор на Kotlin
fun main(args: Array) ( 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) ( ) )
Когато стартирате програмата, изходът ще бъде:
От AuthLog -> Bad Password: 10 пъти
Забележка: Вторичният конструктор трябва да инициализира базовия клас или да делегира на друг конструктор (както в горния пример), ако класът няма първичен конструктор.