Одна из вещей, к которой нужно привыкнуть с новым языком, связана с новыми соглашениями. Сейчас, в основном, из 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.