---
slideOptions:
transition: slide
---
# 4.5. Наследование. Переопределение
---
# План занятия
1. Вспоминаем прошлое занятие
2. Наследование: вспоминаем определение
3. Что такое базовый класс?
4. Переопределение свойств и методов класса
5. Переопределение инициализатора
6. Модификатор *final*
---
# Вспоминаем прошлое занятие
1. Какие бывают свойства?
2. В какой момент вызывается get, а в какой set?
3. Какие бывают наблюдатели?
---
# Наследование
Наследование — это возможность одного класса принимать свойства, методы и остальные характеристики у другого класса.
В рамках наследования «старый» класс называется суперклассом (или базовым классом), а «новый» — подклассом (или субклассом, или производным классом).
#### Синтаксис
```
class SomeSubClass: SomeSuperClass {
// тело подкласса
}
```
Для создания производного класса `SomeSubClass`, для которого базовым является `SomeSuperClass`, необходимо указать имя суперкласса через двоеточие после имени подкласса.
---
# Базовый класс
Любой класс, который ничего не наследует из другого класса, называется базовым классом.
Классы в Swift ничего не наследуют от универсального базового класса. Классы, у которых не указан супер класс (родительский класс), называются базовыми, которые вы можете использовать для строительства других классов.
---
# Переопределение наследуемых элементов
Довольно часто реализация метода, который «достался в наследство» от суперкласса, не соответствует требованиям разработчика. В таком случае в сабклассе нужно переписать данный метод, обеспечив к нему доступ по прежнему имени.
*Сабкласс* может создавать собственные реализации свойств и методов, наследуемых от *суперкласса*. Такие реализации называются **переопределением**. Для переопределения параметров суперкласса в Swift необходимо указать ключевое слово `override` перед определением элемента.
Переопределенный метод не знает деталей реализации метода родительского класса. Он знает лишь имя и перечень входных параметров родительского метода.
---
# Доступ к переопределенным элементам суперкласса
Несмотря на то что переопределение изменяет реализацию свойств и методов, Swift позволяет осуществлять доступ внутри производного класса к переопределенным элементам суперкласса. Для этого в качестве префикса имени элемента используется ключевое слово `super`.
Доступ к переопределенным элементам осуществляется по следующим правилам:
* Переопределенный метод с именем `someMethod()` может вызвать одноименный метод суперкласса, используя конструкцию `super`. `someMethod()` внутри своей реализации (в коде переопределенного метода).
* Переопределенное свойство someProperty может получить доступ к свойству суперкласса с таким же именем, используя конструкцию `super.someProperty` внутри реализации своего геттера или сеттера.
---
# Переопределение инициализаторов
Инициализаторы являются такими же наследуемыми элементами, как и методы. Если в подклассе набор свойств, требующих установки значений, не отличается, то наследуемый инициализатор может быть использован для создания экземпляра подкласса.
Вы можете создать собственную реализацию наследуемого инициализатора.
Если вы определяете инициализатор с уникальным для суперкласса и подкласса набором входных аргументов, то вы не переопределяете инициализатор, а объявляете новый.
Если подкласс имеет хотя бы один собственный инициализатор, то инициализаторы родительского класса не наследуются.
**ВНИМАНИЕ** Для вызова инициализатора суперкласса внутри инициализатора субкласса необходимо использовать конструкцию `super.init()`.
---
# Переопределение наследуемых свойств
Наследуемые свойства иногда ограничивают функциональные возможности субкласса. В таком случае можно переписать геттер или сеттер данного свойства или при необходимости добавить наблюдатель.
С помощью механизма переопределения можно расширить наследуемое «только для чтения» свойство до «чтение-запись», реализовав в нем и геттер и сеттер. Но обратное невозможно: если у наследуемого свойства реализованы и геттер и сеттер, нельзя сделать из него свойство «только для чтения».
**ВНИМАНИЕ** Хранимые свойства переопределять нельзя, так как вызываемый или наследуемый инициализатор родительского класса попытается установить их значения, но не найдет их.
*Сабкласс* не знает деталей реализации наследуемого свойства в суперклассе, он знает лишь имя и тип наследуемого свойства. Поэтому необходимо всегда указывать имя и тип переопределяемого свойства.
---
# Модификатор ***final***
Swift позволяет защитить реализацию класса целиком или его отдельных элементов. Для этого необходимо использовать превентивный модификатор `final`, который указывается перед объявлением класса или его отдельных элементов:
* final class для классов;
* final var для свойств;
* final func для методов;
При защите реализации класса его наследование в другие классы становится невозможным. Для элементов класса их наследование происходит, но переопределение становится недоступным.
---
# Итоги занятия
- Разобрали работу с наследованием
- Узнали, какой класс считается суперклассом, а какой сабклассом
- Изучили переопределение, и как защититься от переопределения
---
## Дополнительные ссылки
[rus] https://swiftbook.ru/content/languageguide/inheritance/
[eng] https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html
---
# Домашнее задание