Разница между тем, что что-то есть, и тем, как что-то ведет себя.
Многие языки пытаются объединить эти два понятия, но это совершенно разные вещи.
Если как и что и как ...
Если все наследуется, object
тогда получаются некоторые преимущества, такие как: любая переменная объекта может содержать любое значение. Но это также проблема, все должно вести себя ( как ) как object
и и похоже ( что ) object
.
Но:
- Что если у вашего объекта нет значимого определения равенства?
- Что делать, если у него нет значимого хэша?
- Что если ваш объект не может быть клонирован, но объекты могут быть?
Либо object
тип становится по существу бесполезным - из-за объекта, не обеспечивающего общности во всех возможных экземплярах. Или же будут существовать объекты, у которых есть сломанное / подкаблучное / абсурдное определение некоторого предполагаемого универсального свойства, найденного на основе, object
которое обеспечивает почти универсальное поведение, за исключением ряда уловок.
Если что не связано с тем, как
В качестве альтернативы вы можете оставить раздел « Что и как» . Тогда несколько различных типов (с ничего общего у всех , что ) все это может вести себя таким же образом , как видно из соавтора Хау . В этом смысле идея Iterator
не является чем-то конкретным , а как . В частности, как вы взаимодействуете с вещами, когда вы еще не знаете, с чем взаимодействуете.
Java (и аналогичные) позволяют подходить к этому с помощью интерфейсов. Интерфейс в этом отношении описывает средства связи и, неявно, протокол связи и действий, которые соблюдаются. Любое То, что заявляет о себе как о данном Как , заявляет, что оно поддерживает соответствующие коммуникации и действия, изложенные в протоколе. Это позволяет любому Соавтор полагаться на Хау и не увязнуть, указав , какие именно Какие «s могут быть использованы.
C ++ (и аналогичные) позволяют подходить к этому посредством утки. Шаблону не важно, объявляет ли сотрудничающий тип, что он следует поведению, только в пределах данного контекста компиляции, с которым объект может взаимодействовать определенным образом. Это позволяет указателям C ++ и объектам, перекрывающим определенные операторы, использоваться одним и тем же кодом. Потому что они соответствуют контрольному списку, чтобы считаться эквивалентным.
- поддерживает * a, a->, ++ a и a ++ -> итератор ввода / вывода
- поддерживает * a, a->, ++ a, a ++, --a и a-- -> двунаправленный итератор
Базовый тип даже не должен выполнять итерации контейнера, это может быть что угодно . Кроме того, это позволяет некоторым соавторам быть еще более универсальными, представьте, что функция нуждается только в ней a++
, итератор может удовлетворить это, как и указатель, так и целое число, так же как и любой объект, реализующий operator++
.
Под и над спецификацией
Проблема с обоими подходами находится под и над спецификацией.
Использование интерфейса требует, чтобы объект объявил, что поддерживает заданное поведение, что также означает, что создатель должен наполнить его с самого начала. Это приводит к некоторому Что «S , чтобы не делать разрез, так как они не объявляли его. Это также означает , что когда - нибудь , что имеет общий предок, интерфейс , представляющий Хау . Это круг назад к первоначальной проблеме object
. Это заставляет соавторов переопределять свои требования, одновременно вызывая невозможность использования некоторых объектов из-за отсутствия объявлений или скрытых ошибок, так как ожидаемое поведение плохо определено.
Использование шаблона требует, чтобы соавтор работал с совершенно неизвестным « Что» , и через свои взаимодействия он определяет « Как» . В некоторой степени это усложняет написание коллабораторов, так как он должен анализировать What для своих примитивов связи (функции / поля / и т. Д.), Избегая при этом ошибок компиляции, или, по крайней мере, указывать, как данное What не соответствует его требованиям для How . Это позволяет коллаборационисту требовать абсолютного минимума от любого заданного « Что» , что позволяет широчайший диапазон того, что должно быть использовано. К сожалению, у этого есть недостаток, позволяющий бессмысленное использование объектов, которые технически предоставляют коммуникационные примитивы для данногоКак , но не следуйте подразумеваемому протоколу, позволяющему совершать всевозможные плохие вещи.
итераторы
В этом случае Iterator
является Как это сокращение для описания взаимодействия. Все, что соответствует этому описанию, по определению Iterator
. Знание как позволяет нам писать общие алгоритмы и иметь короткий список « как дано конкретное что », которые необходимо предоставить, чтобы заставить алгоритм работать. Этим списком являются функция / свойства / и т. Д., Их реализация учитывает конкретные аспекты алгоритма.