Полиморфное использование
Часть раздела Object Oriented Programming путешествия по C на Coddy — урок 47 из 61.
Задание
ЛегкоДавайте докажем, что полиморфизм действительно работает, написав функцию, которая может обрабатывать любую фигуру через указатель на базовый тип Shape* — будь то Circle или Rectangle.
Опираясь на ваши существующие реализации Circle и Rectangle, вы добавите мощную абстракцию: одну функцию, которая единообразно работает с любым типом фигуры.
Ваш проект будет включать следующие файлы:
shape.h: Ваш базовый интерфейсShapeс типамиDrawFuncиAreaFunc.circle.hиcircle.c: Ваша реализация Circle из предыдущего урока.rectangle.hиrectangle.c: Ваша реализация Rectangle из предыдущего урока.shape.c: Реализуйте новую функцию с именемprocess_shape, которая принимает указательShape*. Эта функция должна вызывать функциюdrawфигуры, затем вызывать её функциюareaи выводить результат с 2 знаками после запятой в форматеArea: X.XX.main.c: Продемонстрируйте полиморфизм в действии. Считайте индикатор типа фигуры (cдля круга,rдля прямоугольника), а затем необходимые размеры. Создайте соответствующую фигуру, затем передайте указатель на её встроенный членShapeв функциюprocess_shape. Одна и та же функция обрабатывает оба типа!
Ваша программа получит либо:
c, за которым следует значение радиуса, илиr, за которым следуют значения ширины и высоты
Пример вывода, когда входные данные c и 5.0:
Drawing Circle with radius: 5.00
Area: 78.54Пример вывода, когда входные данные r, 4.0 и 3.0:
Drawing Rectangle with width: 4.00 and height: 3.00
Area: 12.00Магия здесь заключается в том, что process_shape понятия не имеет, работает ли она с Circle или Rectangle — она знает только об интерфейсе Shape. Приводя встроенный член Shape вашей конкретной фигуры к Shape*, вы можете передать любой тип фигуры в эту единственную функцию. Это и есть полиморфизм: одна функция, множество вариантов поведения в зависимости от фактического типа объекта.
Не забудьте объявить process_shape в shape.h, чтобы её можно было вызвать из main.c.
Попробуйте сами
#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Считать символ для типа фигуры ('c' для circle, 'r' для rectangle)
// TODO: Если 'c', считать радиус, создать Circle и вызвать process_shape с его base
// TODO: Если 'r', считать ширину и высоту, создать Rectangle и вызвать process_shape с его base
return 0;
}
Все уроки раздела Object Oriented Programming
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация круга