Абстрактные классы
Как выглядит животное?
- Уже успели ответить? На самом деле, ответа на этот вопрос нет, так как для ответа требуется уточнить, какое именно животное.
Получается, что понятие "животное" - абстрактное.
Как выглядит геометрическая фигура? - Уже успели ответить? Я думаю, что нет, ведь здесь то же требуется уточнение, о какой именно геометрической фигуре идёт речь. Получается, что понятие "геометрическая фигура" - абстрактное.
Примеров обстрактных понятий можно приводить много...
Язык программирования C++ поддерживает объектно-ориентированный подход к разработке приложений.
А придумана парадигма ООП была для того, что-бы программисты могли в коде описать реальные сущности.
Но как же быть с абстрактными понятиями?
- На этот случай, в ООП придумали абстрактные классы. От них нельзя создать объект, зато от них можно наследоваться.
Абстрактный класс - это класс, который содержит хотя бы одну чистую виртуальную функцию и не может быть использован для создания объектов напрямую.
или
Абстрактные классы — это классы, которые не могут быть инстанцированы непосредственно и могут содержать абстрактные методы (методы без реализации) и обычные методы (с реализацией). Они служат основой для других классов, предоставляя общий интерфейс и функциональность для их расширения(наследования).
Чистые виртуальные функции
Чистая виртуальная функция объявляется с помощью = 0
в конце объявления:
-
sound()
- чистая виртуальная функция, не имеет реализации в базовом классе -
Класс, содержащий хотя бы одну чистую виртуальную функцию, становится абстрактным
-
Можно создавать обычные методы с реализацией (как
run()
) -
Виртуальный деструктор необходим для корректного удаления объектов через указатель на базовый класс
Для создания конкретного класса, который будет наследовать абстрактный класс, необходимо реализовать его абстрактные (virtual
) методы.
Наследование от абстрактного класса
Класс Cat (наследует Animal):-
Производные классы должны реализовать все чистые виртуальные функции
-
Ключевое слово
override
явно указывает на переопределение метода -
Если не реализовать все чистые виртуальные функции, класс останется абстрактным
Использование абстрактных классов
-
Можно создавать указатели и ссылки на абстрактный класс
-
Нельзя создавать объекты абстрактного класса напрямую
-
Полиморфные вызовы работают корректно благодаря виртуальным функциям
-
Важно не забывать освобождать память (или использовать умные указатели)
Практический пример: геометрические фигуры
-
Shape
- абстрактный класс с двумя чистыми виртуальными функциями -
Circle
иRectangle
реализуют специфичные версии этих методов -
Используется полиморфизм через указатели на базовый класс
-
Применены умные указатели для автоматического управления памятью
-
Каждая фигура реализует свою версию расчета площади и вывода информации
Практический пример: Музыкальные инструменты и исполнители
Суть задания
Задание демонстрирует принципы полиморфизма в C++ через моделирование взаимодействия музыкантов с различными музыкальными инструментами. Основная цель - показать, как:
-
Создается иерархия классов музыкальных инструментов
-
Реализуется полиморфное поведение через виртуальные функции
-
Класс-исполнитель может работать с любым инструментом через общий интерфейс
-
Достигается гибкость и расширяемость кода
Базовый класс Instrument
-
Содержит чисто виртуальную функцию
MakeSound()
-
Является абстрактным классом (нельзя создать объект)
-
Определяет общий интерфейс для всех музыкальных инструментов
Конкретные классы инструментов
-
Наследуют от базового класса
Instrument
-
Реализуют свою версию метода
MakeSound()
-
Каждый инструмент имеет уникальное звучание
Класс Performer
-
Содержит указатель на
Instrument
(абстрактный класс) -
Может работать с ЛЮБЫМ инструментом, наследующим от
Instrument
-
Метод
play()
вызывает полиморфный методMakeSound()
Работа в main()
-
Создаются конкретные инструменты через указатели на базовый класс
-
Создаются исполнители, которым передаются инструменты
-
При вызове
play()
происходит полиморфный вызов нужной реализацииMakeSound()
-
В конце освобождается выделенная память
Полный код:
Зачем использовать абстрактные классы?
- Упрощение структуры кода: Позволяет создать общую базу, от которой будут наследоваться дочерние классы.
- Полиморфизм: - Позволяет обращаться к объектам разных классов через один интерфейс.
Абстрактные классы являются мощным инструментом в Java для построения архитектуры программ, которая подчеркивает принципы наследования и полиморфизма, способствуя созданию более чистого и понятного кода.