Инициализация представляет процесс подготовки объекта класса, структуры или перечисления к использованию. Этот процесс может включать установку начальных значений для свойств класса.
Для создания объекта класса используется инициализатор. Каждый класс имеет инициализатор по умолчанию:
class User { var age: Int = 0 var name: String = "" } var tom: User = User()
Выражение User()
преставляет вызов инициализатора.
Важно, что хранимые свойства класса (то есть переменные и константы) должны быть инициализированы и иметь определенное значение ко времени создания объекта класса. В данном случае свойствам класса name и age напрямую присваиваются значения. Но также для инициализации свойств может использоваться инициализатор.
Для переопределения инициализатора в классе нам надо использовать ключевое слово init:
class User { var age: Int var name: String init(){ age = 22 name = "Tom" } func getUserInfo(){ print("Имя: \(name); возраст: \(age)") } } var tom: User = User() tom.getUserInfo() // Имя: Tom; возраст: 22
Стоит отметить, что так как переменным name и age не присваиваются начальные значения, а их инициализация производится в инициализаторе, то можно определить эти переменные как константы:
class User { let age: Int let name: String init(){ age = 22 name = "Tom" } }
Фактически инициализатор представляет функцию, которая выполняет начальную инициализацию объекта.
При необходимости мы можем определять дополнительные инициализаторы:
class User { var age: Int var name: String init(){ age = 22 name = "Tom" } init(name: String, age: Int){ self.age = age self.name = name } func getUserInfo(){ print("Имя: \(self.name); возраст: \(self.age)") } } var bob: User = User(name: "Bob", age: 34) bob.getUserInfo() // Имя: Bob; возраст: 34
Второй инициализатор принимает два параметра name и age для установки свойств класса. Так как параметры и свойства класса называются одинаково, то для их разграничения вместе с названиями свойств используется ключевое слово self.
И при создании объекта в данном случае используется второй инициализатор: var bob: User = User(name: "Bob", age: 34)
Инициализаторы могут определять значения по умолчанию для параметров. Так, пример выше мы могли бы сократить следующим образом:
class User { var age: Int var name: String init(name: String = "Tom", age: Int = 22){ self.age = age self.name = name } func getUserInfo(){ print("Имя: \(self.name); возраст: \(self.age)") } } var tom = User() tom.getUserInfo() // Имя: Tom; возраст: 22
Одни инициализаторы могут вызывать другие. Вызывающие инициализаторы должны быть определены с ключевым словом convenience:
class User { var age: Int var name: String convenience init(){ self.init(name: "Tom", age: 22) } init(name: String, age: Int){ self.age = age self.name = name } func getUserInfo(){ print("Имя: \(self.name); возраст: \(self.age)") } } var tom: User = User() tom.getUserInfo() // Имя: Tom; возраст: 22
Специальная разновидность инициализаторов (Failable Initializer) позволяет возвратить значение nil, если в процессе инициализации объекта произошла какая-нибудь ошибка. Например:
class User{ var name: String var age: Int init?(name: String, age: Int){ self.name = name self.age = age if(age < 0){ return nil } } } var bob: User = User(name: "Bob", age: 34)! print(bob.name) // Bob
Поскольку пользователь, представленный классом User, в принципе не может иметь возраст меньше нуля. Поэтому ситуация, когда для возраста передается число меньше нуля, может рассматриваться как ошибочная. И в этом случае мы как раз можем использовать failable-инициализатор.
Для определения такого инициализатора после слова init
ставится знак вопроса, а в самом инициализаторе можно предусмотреть ситуацию,
при которой он возвращает значение nil:
init?(name: String, age: Int){ self.name = name self.age = age if(age < 0){ return nil } }
Возвращая nil, мы тем самым указываем, что мы не можем создать объект User по тем данным, которые переданы в инициализатор.
Важно учитывать, что объект, создаваемый этим инициализатором, будет представлять не тип User, а тип User?
.
Поэтому для получения значения нам надо еще использовать операцию ! (восклицательный знак):
var bob: User = User(name: "Bob", age: 34)!
Либо мы можем напрямую работать с объектом User?:
var bob: User? = User(name: "Bob", age: 34)
Однако надо учитывать, что если мы передадим неправильные данные, то инициализатор возвратит nil, и получение значение окончится ошибкой. Поэтому в таких случаях перед использованием объекта мы можем проверять на наличие значения:
if let lora = User(name: "Lora Palmer", age: -4){ print(lora.name) }