Видеокурсы по изучению языка программирования Swift. Подробнее

Сравнение классов и структур

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Классы и структуры в Swift имеют много общего. И в классах и в структурах можно:

  • Объявлять свойства для хранения значений
  • Объявлять методы, чтобы обеспечить функциональность
  • Объявлять индексы, чтобы обеспечить доступ к их значениям, через синтаксис индексов
  • Объявлять инициализаторы, чтобы установить их первоначальное состояние
  • Они оба могут быть расширены, чтобы расширить их функционал за пределами стандартной реализации
  • Они оба могут соответствовать протоколам, для обеспечения стандартной функциональности определенного типа

Для получения дополнительной информации смотрите главы Свойства, Методы, Индексы, Инициализация, Расширения и Протоколы.

Классы имеют дополнительную возможность, которых нет у структур:

  • Наследование позволяет одному классу наследовать характеристики другого
  • Приведение типов позволяет проверить и интерпретировать тип экземпляра класса в процессе выполнения
  • Деинициализаторы позволяют экземпляру класса освободить любые ресурсы, которые он использовал
  • Подсчет ссылок допускает более чем одну ссылку на экземпляр класса. Для получения дополнительной информации смотрите Наследование, Приведение типов, Деинициализаторы и Автоматический подсчет ссылок.

Заметка

Структуры всегда копируются, когда они передаются в вашем коде, и при этом не используют подсчета ссылок.

Синтаксис объявления

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

class SomeClass {
    // здесь пишется определение класса
}
struct SomeStructure {
    // здесь пишется определение структуры
}

Заметка

Чего бы вы не создавали, новый класс или структуру, вы фактически создаете новый тип в Swift. Назначайте имена типов, используя UpperCamelCase(SomeClass или SomeStructure), чтобы соответствовать стандартам написания имен типов в Swift (например, String, Int и Bool). С другой стороны, всегда назначайте свойствам и методам имена в lowerCamelCase (например, frameRate и incrementCount), чтобы отличить их от имен типов.

Пример определения структуры и класса:

struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

Пример выше объявляет новую структуру Resolution для описания разрешения монитора в пикселях. Эта структура имеет два свойства width, height. Хранимые свойства - или константы или переменные, которые сгруппированы и сохранены в рамках класса или структуры. Этим свойствам выведен тип Int, так как мы им присвоили целочисленное значение 0.

В примере мы так же объявили и новый класс VideoMode, для описания видеорежима для отображения на видеодисплее. У класса есть четыре свойства в виде переменных. Первое - resolution, инициализировано с помощью экземпляра структуры Resolution, что выводит тип свойства как Resolution. Для остальных трех свойств новый экземпляр класса будет инициализирован с interlaced = false, frameRate = 0.0 и опциональным значением типа String с названием name. Это свойство name автоматически будет иметь значение nil или "нет значения для name", потому что это опциональный тип.

Экземпляры класса и структуры

Объявление структуры Resolution и класса VideoMode только описывают как Resolution и VideoMode будут выглядеть. Сами по себе они не описывают специфическое разрешение или видеорежим. Для того чтобы это сделать нам нужно создать экземпляр структуры или класса.

Синтаксис для образования экземпляра класса или структуры очень схож:

let someResolution = Resolution()
let someVideoMode = VideoMode()

И классы и структуры используют синтаксис инициализатора для образования новых экземпляров. Самая простая форма синтаксиса инициализатора - использование имени типа и пустые круглые скобки сразу после него Resolution(), VideoMode(). Это создает новый экземпляр класса или структуры с любыми инициализированными свойствами с их значениями по умолчанию. Классы и структуры инициализации описаны более подробно в главе Инициализация.

Доступ к свойствам

Вы можете получить доступ к свойствам экземпляра, используя точечный синтаксис. В точечном синтаксисе имя свойства пишется сразу после имени экземпляра, а между ними вписывается точка (.) без пробелов:

print("The width of someResolution is \(someResolution.width)")
// Выведет "The width of someResolution is 0"

В этом примере someResolution.width ссылается на свойство width экземпляра someResolution, у которого начальное значение равно 0.

Вы можете углубиться в подсвойства, например, свойство width свойства resolution класса VideoMode:

print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// Выведет "The width of someVideoMode is 0"

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

someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// Выведет "The width of someVideoMode is now 1280"

Заметка

В отличии от Objective-C, в Swift вы можете устанавливать подсвойства структуры напрямую. В последнем примере выше свойство width свойства resolution экземпляра класса someVideoMode устанавливается напрямую, без необходимости менять все свойство resolution на новое значение.

Поэлементные инициализаторы структурных типов

Все структуры имеют автоматически генерированный "поэлементный инициализатор", который вы можете использовать для инициализации свойств новых экземпляров структуры. Начальные значения для свойств нового экземпляра могут быть переданы поэлементному инициализатору по имени:

let vga = Resolution(width: 640, height: 480)

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

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

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

Заметка

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

 

Swift: 
4.0