Хотя классы и структуры имеют некоторые очевидные сходства, в этой статье перечислены различия между структурами и классами, о которых вам следует знать.

Вступление

Swift - это язык с открытым исходным кодом, выпущенный Apple в 2014 году. Он быстро стал одним из популярных современных языков программирования, которые изучают и используют разработчики.

Swift - это универсальный язык программирования, используемый для таких задач, как разработка приложений для iOS и даже машинное обучение.

Структуры и классы - это две фундаментальные конструкции в языке программирования Swift. Оба они могут использоваться для определения объектов, которые имеют инкапсулированные свойства и функции.

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

Различия

  • Наследование
  • Членские инициализаторы
  • Типы значений и ссылок
  • Бонус

1. Наследование (класс)

Наследование присутствует только в классах.

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

Классы, которые наследуют методы и свойства от другого класса, известны как подклассы. Классы, которые предоставляют свои свойства и методы подклассу, являются суперклассами.

В приведенном ниже примере показано, как концепция наследования работает в Swift.

Мы определим класс «Собака», который имеет общие свойства, присущие реальной собаке. Класс Dog также будет содержать функцию «bark», которая распечатает строку «woof woof», чтобы имитировать действие лая.

BullDog - это подкласс, который наследует свойства и функции, определенные в суперклассе Dog.

Чтобы продемонстрировать наследование внутри классов, создается экземпляр класса BullDog, и мы проверим, что подкласс успешно унаследовал свойства от суперкласса Dog.

Подкласс «BullDog» также может обращаться к функции «bark» в суперклассе Dog.

2. Поэлементные инициализаторы (структура)

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

В Swift, когда мы проводим процесс инициализации класса или структуры, создается экземпляр объекта. Берется чертеж определенного объекта (класса или структуры), и на его основе создается объект-экземпляр.

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

Поэлементные инициализаторы, с другой стороны, присутствуют только в реализации структур и не присутствуют в классах.

Последовательные инициализаторы в действии:

Ниже представлен объект структуры Dog со свойствами, представляющими общие черты реальной собаки.

Без необходимости реализовывать настраиваемый инициализатор с помощью функции «init ()» для инициализации свойств, мы все равно можем получить доступ к свойствам структуры и изменить их. Это показано в списке ниже.

Расширенные поэлементные инициализаторы (Swift 5.1+)

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

В последней версии Swift есть возможность исключить определение некоторых свойств при создании экземпляров структур.

До версии Swift 5.1 это приводило бы к ошибке.

3. Значения и ссылочные типы

Структуры - это типы значений, а классы - это ссылочные типы.

  • Ссылочный тип (классы): когда эти типы выделяются переменной, константе или передаются функции, они не копируются, а просто новый распределитель указывает положение данных в памяти.
  • Тип значения (структуры): это типы (целые числа, логические значения, строки и т. д.), значения которых дублируются и копируются при назначении переменной-заполнителю, константе или передаче в качестве аргументов / параметров функции.

Вот пример, показывающий свойство типа значения структур:

Предположим, у нас есть таблица со следующими атрибутами: ‘noOfLegs’, ’color’ и ‘ComeWithChair’. Мы определяем структуру, фиксирующую свойства, как показано в сущности ниже.

Наш воображаемый персонаж, Джеймс, хочет купить стол в магазине и переходит к тому, чтобы получить стол, который выставлен в магазине.

Затем другой клиент по имени Сара хочет тот же стол, который купил Джеймс, но не хочет стул.

Мы проверим, довольны ли Джеймс и Сара своими новыми столами.

Когда Сара попросила столик, мы не забрали столик, который был у Джеймса, мы взяли другой стол и передали его Саре.

Все довольны.

Чтобы проиллюстрировать, как работают ссылочные типы в Swift, мы создадим новый класс «Book». У книги есть свойства: название, страницы и имя текущего владельца.

Джеймс покупает новую книгу по изучению основ языка программирования Swift. Он находит книгу «Learning Swift», берет ее и начинает писать свое имя на ней.

Джеймс, довольный своей новой книгой, кладет ее на стол.

Оказывается, Сара изучает Swift, и она тоже берет ту же книгу, которую Джеймс взял со стола ранее, «Learning Swift».

Нынешним владельцем книги «Learning Swift» теперь является Сара, а не Джеймс.

Давай докажем это.

Книга Джеймса теперь принадлежит Саре, потому что вместо того, чтобы Сара получила новый экземпляр книги «Learning Swift», она взяла книгу Джеймса. Это пример того, как ссылочные типы работают в Swift. В отличие от создания копии данных, хранящихся в памяти, когда данные назначаются новой переменной или константе, новая переменная или константа указывает на расположение данных в памяти. Это означает, что изменение, сделанное с помощью одной переменной, отражается во всех переменных, указывающих на данные в памяти.

Бонус

Такие типы, как строки, словари и массивы, считаются типами значений в Swift.

В Swift, Array, String и Dictionary - это все типы значений - https://developer.apple.com/swift/blog/?id=10

Но это не совсем так.

Типы значений копируют данные и присваивают их новым переменным. Копирование стоит довольно дорого с точки зрения производительности. Чтобы обуздать проблему неэффективной производительности в Swift, типы значений не копируются немедленно, когда они назначаются новым переменным или константам. Новая переменная / константа ведет себя как ссылочный тип, и копия создается только после внесения изменений.

Это проиллюстрировано в списке ниже.

Мы инициализируем две переменные с помощью строк. Первая переменная, 'one', представляет собой простую строку (тип значения), а вторая переменная 'two' инициализируется копией данных, хранящихся в переменной ' один.

В соответствии с поведением, ожидаемым типами значений, содержимое переменных ’one’ и «two’ является копиями одних и тех же данных и должно храниться в разных адресах памяти.

Вместо двух отдельных адресов памяти для данных, содержащихся в переменных, у нас есть переменные один и два, указывающие на один и тот же адрес памяти. Это эффективная производительность, реализованная в Swift при копировании данных.

При внесении изменений данные действительно копируются. В этот момент, когда мы изменяем переменную «two», мы должны увидеть, что адреса памяти - это разница.

Заключение

Вот и все, очевидные различия между структурами и классами в Swift, и если они не были для вас такими очевидными, я надеюсь, что вы узнали что-то новое из этой статьи.

Я очень скоро напишу о сходстве между классами и структурами, следите за мной, чтобы быть в курсе, когда статья будет выпущена.