Одна из вещей, к которой нужно привыкнуть с новым языком, связана с новыми соглашениями. Сейчас, в основном, из Java и Ruby, существует понятие конструкторов и цепочек конструкторов, в основном, когда один конструктор вызывает другой. Поэтому, когда речь заходит о Swift, есть несколько правил относительно методов, используемых для создания объектов.
Во-первых, руководство по языку ссылается на конструкторы как инициализаторы. Поэтому, в основном, всякий раз, когда вы хотите использовать термин «конструктор», используйте термин «инициализатор», когда вы находитесь на территории Swift. Более конкретно, цепочка конструктора называется делегированием инициализатора.
Инициализаторы делятся на две категории: Назначенные и Удобные . Назначенные инициализаторы являются основными инициализаторами и отвечают за инициализацию всех свойств класса. Таким образом, в этом случае единственный инициализатор здесь известен как Назначенный .
class Person {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Теперь, если вы хотите добавить другие инициализаторы для делегирования назначенному , они будут называться удобными инициализаторами. Итак, давайте добавим тот, который по умолчанию возраст. У удобных инициализаторов есть ключевое слово удобство перед ними.
class Person {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init(name: String) {
self.init(name: name, age: 100)
}
}
Инициализаторы удобства должны быть делегированы другому инициализатору удобства или назначенному инициализатору.
Вот пример удобства инициализатора вызов другого Convenience один.
class Person {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init(name: String) {
self.init(name: name, age: 30)
}
convenience init() {
self.init(name: "Homer")
}
}
Если вы хотите, вы можете создать другой назначенный инициализатор. Теперь у нас есть два назначенных инициализатора и два удобных инициализатора.
class Person {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
init(age: Int, name: String) {
self.age = age
self.name = name
}
convenience init(name: String) {
self.init(name: name, age: 30)
}
convenience init() {
self.init(name: "Homer")
}
}
Как насчет подклассов?
Еще раз, с инициализаторами, есть определенные правила, которые необходимо соблюдать при создании подклассов. Поэтому назначенные инициализаторы должны вызывать другие назначенные инициализаторы в своем непосредственном родительском классе.
Итак, давайте посмотрим на пример. Мы добавляем класс Student как подкласс класса Person. Это добавит номер студента собственности.
class Student : Person {
let number: String
init(name: String, age: Int, number: String) {
self.number = number
super.init(name: name, age: age)
}
}
Здесь мы вызываем назначенный инициализатор в классе Person. Если мы попытаемся вызвать один из инициализаторов Convenience в классе Person, произойдет ошибка компиляции. Также обратите внимание, что нам нужно назначить свойство number перед вызовом инициализатора в родительском классе, так как это является обязательным требованием, чтобы все свойства были инициализированы в дочерних классах до вызова их соответствующего родительского инициализатора.
Резюме
В целом, как объясняется в руководстве по языку, назначенные инициализаторы делегируются вверх, а удобные инициализаторы делегируются между ними. Я надеюсь, что эта статья помогла как-то улучшить ваше понимание инициализаторов в Swift.