Классы в Swift [Часть 1]

от автора

Недавно Apple представила общественности достаточно важное изменение в разработке iOS приложений, анонсировав новый язык программирования Swift. В настоящее время, количество материалов на русском, посвящённых этому языку, ограничено. Также Swift — язык объектно-ориентированный, и классы в нём — основа основ. Поэтому я решил перевести эту статью.

Создание классов

Для создания новых классов используется ключевое слово class, название класса и фигурные скобки, внутри которых объявляются свойства и методы класса.

class Point {     var x = 0.0 // sets the default value of x to 0     var y = 0.0 // sets the default value of x to 0 }  // this creates a new Point instance using the default initializer var point = Point()  point.x = 100 // sets the x property to 100 point.y = 200 // sets the y property to 200 

Инициализаторы

Из официальной документации Apple:

Инициализация — процесс подготовки экземпляра класса, структуры или перечисления для дальнейшего использования. Он включает в себя инициализацию каждого свойства и выполнение других настроек или инициализаций, необходимых до первого использования.

Процесс инициализации реализуется с помощью инициализаторов, которые являются специальными методами, вызывающимися при объявлении новых экземпляров класса. В отличие от Objective-C, в Swift инициализаторы ничего не возвращают, т.к. они обеспечивают правильность инициализации новых экземпляров класса.

Обратимся к примеру

class Point {     var x     var y } 

Запустив его, вы получите три ошибки компиляции

class Point { // Class 'Point' has no initializers (класс <code>Point</code> не содержит инициализаторов)     var x // Type annotation missing in pattern (Отсутствует аннотация типа)     var y // Type annotation missing in pattern (Отсутствует аннотация типа) } 

Чтобы исправить ситуацию, давайте зададим тип каждого свойства

class Point {     var x: Double     var y: Double } 

Инициализатор задаётся ключевым словом init. У инициализатора может быть несколько параметров, а может их вообще не быть

class Point {      var x: Float     var y: Float      init(x: Float, y: Float) {         self.x = x         self.y = y     } }  // Example usage var point = Point(x: 100, y: 200) 

Также мы можем установить опциональные значения свойств. Чтобы это сделать, просто поставьте ? после типа, как показано в примере. Если объявить свойство подобным образом, то оно будет иметь значение по умолчанию nil.

class Point {      var x: Float?     var y: Float? }  var point = Point() // both the x and y properties are now set to nil  point.x = 100.0 point.y = 200.0 

Перегрузка инициализаторов

Представим, что во время создания проекта появилась необходимость использовать список пользователей. Давайте для начала создадим класс User. Каждый объект класса будет иметь следующие поля: имя (firstName), фамилию (lastName), краткую информацию о пользователе (bio). Поля имени и фамилии будут иметь опциональные значения, а поле краткой информации — значение по умолчанию (т.е. это поле будет дополнительным).

class User {     var firstName: String?     var lastName: String?     var bio: String = "I ♡ Swift!" }  var user = User() // user = { firstName: nil, lastName: nil, bio: "I ♡ Swift!"} 

Ну что ж, класс мы написали. Теперь пришло время создать первых пользователей. Поле краткой информации — дополнительное, значит нам нужно перегрузить инициализатор, т.к. можно как написать что-то про игрока, так и оставить его тёмной личностью. Ну что ж, давайте напишем инициализаторы для обоих случаев

class User {     var firstName: String     var lastName: String     var bio: String = "I ♡ Swift!"      // no bio provided     init(firstName: String, lastName: String) {         self.firstName = firstName         self.lastName = lastName     }      // bio provided     init(firstName: String, lastName: String, bio: String) {         self.firstName = firstName         self.lastName = lastName         self.bio = bio     } }  var me = User(firstName: "Andrei", lastName: "Puni") // me = { firstName: "Andrei", lastName: "Puni", bio: "I ♡ Swift!"}  var silviu = User(firstName: "Silviu", lastName: "Pop", bio: "I f**ing ♡ Swift!!!") // silviu = { firstName: "Silviu", lastName: "Pop", bio: "I f**ing ♡ Swift!!!"} 

Однако согласитесь, это не совсем рационально, ведь отличия в инициализации минимальные — про кого-то есть какая-то информация, а про кого-то — нет. Поэтому давайте напишем один инициализатор, а аргументу bio дадим значение по умолчанию.

class User {     var firstName: String     var lastName: String     var bio: String      init(firstName: String, lastName: String, bio: String = "I ♡ Swift!") {         self.firstName = firstName         self.lastName = lastName         self.bio = bio     } }  var me = User(firstName: "Andrei", lastName: "Puni") // me = { firstName: "Andrei", lastName: "Puni", bio: "I ♡ Swift!"}  var silviu = User(firstName: "Silviu", lastName: "Pop", bio: "I f**ing ♡ Swift!!!") // silviu = { firstName: "Silviu", lastName: "Pop", bio: "I f**ing ♡ Swift!!!"} 

Идентичность классов

Из официальной документации Apple:

Операторы идентичности

Поскольку класс является ссылочным типом, может возникнуть ситуация, когда один и тот же экземпляр класса обозначается несколькими переменными или константами. (Это невозможно для структур и перечислений, т.к. и те, и другие являются значимыми типами и копируются при присваивании и передаче в функцию в качестве параметров)

Иногда полезно выяснить, что две переменные или константы ссылаются на один и тот же экземпляр класса. Для этого в Swift существуют два оператора:
Идентичны (===)
Не идентичны (!==)

Предположим, что у нас есть список игроков, один из них — владелец замка. Нам необходимо добавить какие-то функции для игроков, не являющихся владельцами замка. Для этого давайте используем оператор идентичности (===)

var users: User[] = [ ... ] // User[] means Array of Users var host = /* some user */    for user in users {     if user === host {         // host logic here         println("this is the host")     } else {         // guest logic here         println("this is a guest")     } } 

Оператор равенства == не работает при сравнении объектов классов, так что вам не следует бояться подобных ошибок.

В следующей части мы рассмотрим наследование классов и протоколы.

Полезен ли перевод для вас?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Никто ещё не голосовал. Воздержавшихся нет.

ссылка на оригинал статьи http://habrahabr.ru/post/231739/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *