Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
25
Добавлен:
27.02.2014
Размер:
84.99 Кб
Скачать

Рекурсия

Реку́рсия — метод определения класса объектов или методов предварительным заданием одного или нескольких (обычно простых) его базовых случаев или методов, а затем заданием на их основе правила построения определяемого класса.

Другими словами, рекурсия — частичное определение объекта через себя, определение объекта с использованием ранее определённых. Рекурсия используется, когда можно выделить самоподобие задачи.

Определение в логике, использующее рекурсию, называется индуктивным (см., например, Натуральное число).

Рекурсия в программировании

В программировании рекурсия — вызов функции (процедуры) из неё же самой, непосредственно (простая рекурсия) или через другие функции (сложная рекурсия), например, функция A вызывает функцию B, а функция B — функцию A. Количество вложенных вызовов функции или процедуры называется глубиной рекурсии.

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

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

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

Описание типа данных может содержать ссылку на саму себя. Подобные структуры используются при описании списков и графов. Пример описания списка (C++):

class element_of_list; /* необходимо по правилам C++ */

class element_of_list

{ element_of_list *next; /* ссылка на следующий элемент того же типа */

int data; /* некие данные */};

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

Наследование интерфейса - обязательство реализации реализовать не только "свои" методы, но и методы базовых абстрактных классов. Как она будет это делать - декларацию интерфейса не касается. Но очевидно, что каждому методу интерфейса-наследника (и всех методов базовых интерфейсов в него входящих) следует определить реализующий метод обычного класса. Т.е. реализация наследования интерфейсов может быть сделана только путём включения и не может быть сделана путём агрегирования, поскольку на этапе компиляции компилятор заявит, что увидел абстрактный метод, которому в данном коде он не нашёл реализации.

Когда какой способ наследования следует применять? Если интерфейсы X и Y связаны синтаксически, т.е. методы X не имеют никакого смысла без того, чтобы ранее не были определены методы Y, и это обстоятельство не зависит от реализации (т.е. любая реализация будет вынуждена поступать именно так и никак иначе), то в данном случае имеет место быть наследование интерфейса. Требование COM, чтобы всякий интерфейс реализовывал в себе IUnknown есть хороший тому пример - всякий интерфейс обязан наследовать интерфейсу IUnknown, каким бы образом он ни реализовывался.

Если же, напротив, интерфейсы X и Y связаны семантически, т.е. смыслом именно такой, а не какой-то иной реализации, то в данном случае имеет место быть наследование реализации. В каком виде: в виде агрегирования или в виде включения - зависит от обстоятельств. Технических, маркетинговых или иных. Теоретически, оба способа имеют равные выразительные возможности, но несколько разнятся по предъявляемому результату. Например, если базовый интерфейс экспонирует десять методов, а вам в интерфейсе-наследнике следует показать клиенту только один из них, то, вероятно, включение будет более предпочтительным способом, нежели агрегирование - хотя бы из тех соображений, что клиенту не стоит показывать лишнего.

Соседние файлы в папке Ответы на билеты