Різниця між тим, що щось є, і тим, як щось поводиться.
Дуже багато мов намагаються поєднати їх разом, але це досить чіткі речі.
Якщо як що, а що як ...
Якщо все успадковується від object
цього, то виникають певні переваги, такі як: будь-яка змінна об'єкт може мати будь-яке значення будь-коли. Але це теж руб, все повинно вести себе ( як ) як object
, і бути схожим на ( що ) object
.
Але:
- Що робити, якщо ваш об’єкт не має змістовного визначення рівності?
- Що робити, якщо він не має значущого хешу?
- Що робити, якщо ваш об’єкт неможливо клонувати, але об’єкти можуть бути?
Або object
тип стає по суті марним - через об'єкт, що не забезпечує спільності у всіх можливих випадках. Або існуватимуть об'єкти, які мають зламане / взуттєве / абсурдне визначення деякої імовірної універсальної властивості, знайденої на object
яких свідчить майже про універсальну поведінку, за винятком ряду гатчів.
Якщо Що не пов'язане з Як
По черзі можна зберігати розділення Що і як . Тоді декілька різних типів (у них немає нічого спільного взагалі що ) можуть поводитись так само, як видно у співпрацівача як . У цьому сенсі ідея створення Iterator
не є специфічним , що , а як . Зокрема, як ви взаємодієте з річчю, коли ви ще не знаєте, з чим спілкуєтесь.
Java (і подібні) дозволяють підходи до цього за допомогою інтерфейсів. Інтерфейс у зв'язку з цим описує засоби зв'язку та неявно протокол зв'язку та дії, який слід дотримуватися. Будь-яке Що , який заявляє про себе , щоб бути даністю Як , йдеться , що він підтримує відповідні зв'язки і дії , викладені в протоколі. Це дозволяє будь-якому Співавтор покладатися на Хау і не загрузнути, вказавши , які саме Які «s можуть бути використані.
C ++ (і подібні) дозволяють підходити до цього шляхом натискання качки. Шаблон не має значення, якщо тип співпраці заявляє, що він слід за поведінкою, а саме в даному контексті компіляції, з якою об'єкт може взаємодіяти певним чином. Це дозволяє вказівникам C ++ та конкретним операторам, що пересувають об'єкти, використовувати той самий код. Тому що вони відповідають контрольному списку, щоб вважати його рівнозначним.
- підтримує * a, a->, ++ a і ++ -> ітератор вводу / переадресації
- підтримує * a, a->, ++ a, a ++, --a та a-- -> двонаправлений ітератор
Основний тип навіть не повинен бути ітератором контейнера, він може бути будь- яким . Крім того, це дозволяє деяким колабораціоністам бути ще більш загальними, уявіть, що функція лише потребує a++
, ітератор може задовольнити це, так як вказівник, так і ціле число, як і будь-який об'єкт, що реалізує operator++
.
Під і над специфікаціями
Проблема обох підходів полягає в недостатній специфікації.
Використання інтерфейсу вимагає, щоб об'єкт оголосив, що він підтримує задану поведінку, що також означає, що творець повинен перейняти це спочатку. Це призводить до того, що деякі What 's не роблять розріз, оскільки вони не заявляли про це. Це також означає, що коли-небудь, що має спільного предка, інтерфейс, що представляє Як . Це повертається до початкової проблеми object
. Це змушує співпрацівників переоцінювати свої вимоги, в той же час спричиняючи, що деякі об'єкти є або непридатними через відсутність декларації, або приховані дітки, оскільки очікувана поведінка погано визначена.
Використання шаблону вимагає, щоб співпрацівник працював із абсолютно невідомим Що , і завдяки його взаємодії визначав як . В якійсь мірі це ускладнює написання співпрацівників, оскільки він повинен аналізувати що для своїх примітивних комунікацій (функції / поля / тощо), уникаючи помилок компіляції або, принаймні, вказувати на те, як дане те, що не відповідає його вимогам щодо " Як" . Це дозволяє співробітнику вимагати абсолютного мінімуму від будь-якого даного What , що дозволяє найширшому діапазону того, що використовується. На жаль, це має і недолік використання безглуздого використання об'єктів, які технічно забезпечують комунікативні примітиви для даної задачіЯк , але не слідкуйте за прихованим протоколом, що дозволяє всілякі погані речі.
Ітератори
У цьому випадку а Iterator
- це як це скорочення для опису взаємодії. Все, що відповідає цьому опису, за визначенням є Iterator
. Знаючи як дозволяє нам писати загальні алгоритми та мати короткий список " Як дано конкретний Що ", що потрібно надати для того, щоб алгоритм працював. Цей список є функції / властивості / і т.д., їх реалізація враховує специфіку Що , що слухалася алгоритмом.