Действия компьютера как объекта

Обновлено: 06.07.2024

Предметы и простой дизайн класса должны преподаваться вместе. Этот урок показывает, что класс подобен шаблону, а объект в некотором смысле является результатом класса.

На этом уроке можно познакомить с понятием объектов в течение первых нескольких недель обучения в школе. Это позволит вам продолжать обращаться к этому опыту по мере того, как вы формируете у учащихся знания и понимание объектов и классов.

Руководство учителя по преподаванию предметов и классов

Это упражнение представляет собой введение в создание объектов с помощью PLAY-DOH® и формочек для печенья (см. задание 1). Например, использование формы для печенья в виде собаки и кролика полезно, потому что разработка приложения (клиентской программы), такого как «животная ферма», «дошкольная игра с животными», «симуляция», намного проще. Тем не менее, любая формочка для печенья должна работать. Как учителю, очень легко вернуться к разным моментам в течение учебного года и сказать: «Помните PLAY-DOH? Разница между объектом и классом?» Как правило, это следует делать за один или два урока (продолжительностью 55 минут). К концу этих двух дней учащиеся должны иметь хотя бы поверхностное представление о том, что такое объект, а также о разнице между объектом и классом. Затем напишите пример кода (приведенный в презентации) проектирования класса и клиентской программы, которая создает экземпляр объекта класса. Помимо обучения предметам и классам, вы можете расширить этот урок, включив в него другие темы, такие как:

  • Концепция общедоступных и частных переменных.
  • Концепция общедоступных и частных методов. (убедитесь, что метка указывает на общедоступный класс и его последствия)
  • Типы методов (конструктор, методы доступа, модификаторы и деструкторы).
  • Заголовки методов
  • Тип данных, который возвращает каждый метод.
  • Передача параметров.
  • Концепция формальных и фактических параметров
  • Использование оператора точки

Раздайте раздаточный материал с образцом программы, где все эти части помечены и объяснены. После того, как ваши студенты спроектировали класс и клиента во время лабораторных работ, будет полезно еще раз пройтись по этим концепциям. Вероятно, потребуется два урока, чтобы обсудить дизайн класса, прежде чем учащиеся будут готовы к лабораторной работе.

Лабораторная работа: попросите учащихся открыть BlueJ и открыть один из примеров программ. Проект Shapes хорош для использования. (c:\BlueJ\examples\Shapes).

Ниже приведен набор шагов, которые необходимо выполнить в качестве лабораторной работы.

  1. Нажмите правой кнопкой мыши на каждый из прямоугольников: круг, квадрат и треугольник.
  2. Нажмите "Компилировать".
  3. Нажмите на новый круг().
  4. Нажмите "ОК" в диалоговом окне "Новый экземпляр".
  5. Красное поле с надписью "circle1" появляется в нижней части приложения.
  6. Немедленно пройдитесь по комнате и объясните, что прямоугольник с меткой в ​​виде круга — это класс, а красный прямоугольник — объект.
  7. Щелкните объект правой кнопкой мыши, и все отображаемые методы будут доступными для этого объекта.

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

Примечание. Эта визуальная обратная связь о разнице между классом и объектом делает ее очень понятной для студентов, которые не совсем поняли ее во время лекции.

Теперь учащиеся могут открыть JCreator и ввести пример кода (классовые и клиентские программы). Ожидается, что на этом этапе учащиеся успешно скомпилируют и выполнят программы.

Активность в конце темы:

После того, как учащиеся выполнили как минимум три мини-проекта (лабораторные работы) по разработке классов и клиентов, выполнили несколько домашних заданий (множественный выбор, верно или неверно и т. д.), нам нужно выяснить, что они успешно поняли. Упражнение 2 основано на концепции использования карточек CRC (Class-Responsibility-Collaborator). Типичные действия с карточками CRC, кажется, менее успешны в старшей школе, потому что учащиеся находят это скучным. Выставляя это как соревнование, вы имеете больше шансов на успех. Каждая группа получает только один ход. Убедитесь, что вы дали учащимся достаточно времени, чтобы обдумать различные варианты.

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


< бр />

  • Прокрутка — перемещение содержимого (текста, изображений и т. д.) по вертикали или горизонтали на экране компьютера, позволяющее пользователю просматривать различные части информации в окне.
  • Вертикальная полоса прокрутки — вертикальная полоса в правой части окна или экрана, которая позволяет пользователю прокручивать область просмотра окна вверх или вниз.
  • Горизонтальная полоса прокрутки – горизонтальная полоса в нижней части окна или экрана, которая позволяет пользователю прокручивать область просмотра окна влево или вправо.

Прокрутка

  • Вертикальная прокрутка — перемещение содержимого вверх или вниз по экрану компьютера с помощью вертикальной полосы прокрутки.
  • Горизонтальная прокрутка — перемещение содержимого влево или вправо на экране компьютера с помощью горизонтальной полосы прокрутки.

Перетаскивание: нажмите и удерживайте левую кнопку мыши, чтобы захватить объект (например, значок на рабочем столе) и поместить его в другое место.

Сенсорная панель ноутбука (или трекпад) — устройство ввода для портативных компьютеров, состоящее из плоской сенсорной поверхности. Он позволяет перемещать курсор по экрану или давать инструкции (выделять текст, выбирать и открывать приложения и т. д.).

Используйте сенсорную панель ноутбука (или трекпад)


Атрибуция мультимедиа

устройство, используемое для управления движением указателя (курсора) на экране.

наведите указатель на объект на экране, а затем нажмите кнопку мыши, чтобы выбрать объекты/команды, открыть меню/гиперссылки (ссылки) или закрыть окна.

дважды быстро щелкните левой кнопкой мыши по любой папке, файлу или программе, чтобы открыть ее.

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

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

перемещение содержимого (текста, изображений и т. д.) по вертикали или горизонтали на экране компьютера и предоставление пользователю возможности просматривать различные части информации в окне.

вертикальная полоса в правой части окна или экрана, которая позволяет пользователю прокручивать область просмотра окна вверх или вниз.

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

перемещение контента вверх или вниз по экрану компьютера с помощью вертикальной полосы прокрутки.

перемещение содержимого влево или вправо на экране компьютера с помощью горизонтальной полосы прокрутки.

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

небольшая плоская поверхность ноутбука или другого компьютера, выполняющая те же функции, что и мышь.

Интерфейс – это описание действий, которые может выполнять объект. например, когда вы щелкаете выключателем, свет загорается, вам все равно, как, просто так. В объектно-ориентированном программировании интерфейс — это описание всех функций, которые должен иметь объект, чтобы быть «X». Опять же, в качестве примера, все, что "ДЕЙСТВУЕТ КАК" свет, должно иметь метод turn_on() и метод turn_off(). Цель интерфейсов — позволить компьютеру применять эти свойства и знать, что объект ТИПА T (каким бы ни был интерфейс) должен иметь функции с именами X, Y, Z и т. д.

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

Синтаксис интерфейса

Интерфейс имеет очень простой синтаксис, очень похожий на определение класса. публичный интерфейс XYZZY. Внутри <> интерфейса находится список функций, которые должны быть найдены в любом объекте, который претендует на то, чтобы «следовать» интерфейсу.

Интерфейсы помещаются в свои собственные файлы, которые имеют то же имя, что и интерфейс (с заглавной буквы), и заканчиваются знакомым языковым расширением (например, ".as"). Следующий интерфейс будет помещен в файл "Vehicle.as".

Вот пример упомянутого выше интерфейса Vehicle (только частичное определение).

Ниже перечислены различия между интерфейсом и классом.

В интерфейсе нельзя объявлять ПЕРЕМЕННЫЕ.

Интерфейс касается разрешенных действий, а не данных или реализации этих действий.

Ключевое слово public не помещается перед прототипами функций. По определению, все функции, перечисленные в интерфейсе, должны быть общедоступными.

После прототипа функции нет кода. Обычный <> заменяется одной точкой с запятой.

Реализация интерфейса

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

Вот пример класса Car, который реализует определение Vehicle.

Помните: хотя все функции в интерфейсе должны быть реализованы в классе, вы также можете создать любые другие функции для этого класса.

Применение полиморфизма к интерфейсам

В чем сила интерфейса? Сила в том, что если у нас есть несколько классов, реализующих интерфейс, то с какой-то точки зрения они эквивалентны. Например, предположим, что мы хотим создать автомобиль и грузовик, но все, что наша программа хочет сделать, это «завести» их и «водить» их. С «точки зрения» нашей программы это просто Транспортные средства.

Ниже приведены примеры, показывающие, как мы будем писать код без интерфейсов, с интерфейсами, а затем с универсальными массивами «Транспортных средств».

Без интерфейсов

С интерфейсами

Использование массива и полиморфизма

В последнем примере выше показана концепция полиморфизма. Полиморфизм — это идея о том, что во время компиляции (времени кодирования) мы не знаем (и часто не можем знать), каков фактический тип объекта внутри переменной. В приведенном выше массиве транспортных средств мы не знаем, является ли транспортное средство[i] автомобилем, грузовиком, велосипедом и т. д. В компьютерных языках без полиморфизма мы ничего не смогли бы сделать с этими объектами.

Благодаря полиморфизму компьютер запоминает, что такое каждый из них, и когда мы говорим: "item.start_engine();" компьютер решает, если этот объект является грузовиком, вызовите «truck.start_engine()», если этот объект является автомобилем, вызовите «car.start_engine()», если этот объект является XYZZY, вызовите «XYZZY.start_engine()». ;"

Полиморфизм экономит программисту много времени и усилий при кодировании "исключительных" условий. Компьютер делает всю работу за нас: а) запоминает, что на самом деле представляет собой каждый объект, а затем б) во время выполнения вызывает реальную функцию, связанную с текущим объектом.

Конкретный тип в интерфейсе

Иногда вам может потребоваться использовать функцию, специфичную для базового типа. Например, самосвал реализует Vehicle, но дополнительно имеет функцию «raise_bed», которая выгружает все из кузова грузовика. В следующем коде самосвал воспринимается компьютером как Транспортное средство, поэтому код НЕ ИМЕЕТ ДОСТУПА к функции raise_bed.

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

Ключевое слово as.

Чтобы переопределить проверку типов компьютеров, вы можете "взять на себя ответственность" за свою программу и заставить компьютер обрабатывать содержимое переменной транспортного средства как Dump_Truck. Вот правильный код

Предупреждение: если переменная транспортного средства не содержит Dump_Truck (программист допустил ошибку), то в этот момент вся программа "вылетит".

Вы должны стараться не использовать ключевое слово as, за исключением случаев крайней необходимости. Когда мы его не используем, у нас есть гарантия от компьютера, что наши типы правильны. Когда мы его используем, все, что у нас есть, — это уверенность программиста, а программисты часто ошибаются.

Обзор

Интерфейсы служат двум целям:

Они позволяют программисту быть более абстрактным при обращении к объектам (например, var Vehicle : Vehicle может ссылаться на любой автомобиль, грузовик и т. д. на все, что является транспортным средством (и не важно, какого оно типа). Это происходит в "время программы".

При вызове функции Vehicle.start_engine() фактически используется правильная функция, связанная с реальным объектом. Это происходит во время выполнения.

Они требуют от программиста создания определенных функций, которые ожидаются в реализующем классе, когда он реализует интерфейс.

Опять же, это позволяет обрабатывать все объекты в «наборе» похожих объектов на основе типа «высокого уровня» набора, а не на конкретном типе отдельного объекта.

Во многих случаях действия человека можно определить не только по единичному наблюдению за человеческим телом в движении, но и по свойствам окружающей сцены и связанных с ней объектов. В этой статье мы рассматриваем эту проблему и предлагаем подход к распознаванию действий человека, который объединяет несколько каналов функций от нескольких объектов, таких как объекты, сцены и люди. Мы формулируем проблему в структуре обучения с несколькими экземплярами (MIL), основанной на нескольких функциональных каналах. Используя дискриминационный подход, мы объединяем несколько функциональных каналов, встроенных в пространство MIL. Наши эксперименты с большим набором данных YouTube показывают, что информацию о сцене и объекте можно использовать в качестве дополнения к характеристикам человека для распознавания действий человека.

Ключевые слова

  • Особый канал
  • Объект-кандидат
  • Обучение множеству ядер
  • Обучение с использованием нескольких экземпляров
  • Функция сцены

Эти ключевые слова были добавлены машиной, а не авторами. Этот процесс является экспериментальным, и ключевые слова могут обновляться по мере улучшения алгоритма обучения.

Загрузить документ конференции в формате PDF

Ссылки

Али, С., Шах, М.: Распознавание действий человека в видеороликах с использованием кинематических признаков и обучения на нескольких экземплярах. IEEE TPAMI 32(2) (2010 г.)

Эндрюс С., Цочантаридис И., Хофманн Т.: Опорные векторные машины для обучения с несколькими экземплярами. В: NIPS, стр. 561–568. MIT Press, Кембридж (2003 г.)

Бабенко Б., Ян М.-Х., Белонги С.: Визуальное отслеживание с онлайн-обучением на нескольких экземплярах. В: CVPR (2009 г.)

Бланк М., Горелик Л., Шехтман Э., Ирани М., Басри Р.: Действия как формы пространства-времени. В: ICCV (2005 г.)

Команичу, Д., Рамеш, В., Меер, П.: Отслеживание объектов на основе ядра. IEEE TPAMI 25(5), 564–575 (2003 г.)

Далал, Н., Триггс, Б.: Гистограммы ориентированных градиентов для обнаружения человека. В: CVPR, стр. 886–893 (2005 г.)

Эфрос, А.А., Берг, А.С., Мори, Г., Малик, Дж.: Распознавание действия на расстоянии. В: ICCV ’03, стр. 726–733 (2003 г.)

Фельценшвальб П., Макаллестер Д., Раманан Д.: Многомасштабная модель деформируемой детали с дискриминационным обучением. В: CVPR (2008 г.)

Форсайт, Д.А., Арикан, О., Икемото, Л., О'Брайен, Дж., Раманан, Д.: Вычислительные исследования человеческого движения: часть 1, отслеживание и синтез движения. Нашел. Тенденции. вычисл. График Вис. 1(2–3), 77–254 (2005)

Гелер П.В., Новозин С.: О сочетании признаков для многоклассовой классификации объектов. В: ICCV (2009 г.)

Гупта, А., Дэвис, Л.С.: Объекты в действии: подход к объединению понимания действия и восприятия объекта. В: CVPR (2007 г.)

Хан Д., Бо Л., Сминчисеску К.: Выбор и контекст для распознавания действий. В: ICCV (2009 г.)

Ху, Ю., Цао, Л., Лв, Ф., Ян, С., Гонг, Ю., Хуанг, Т.С.: Обнаружение действия в сложных сценах с пространственной и временной неоднозначностью. В: ICCV (2009 г.)

Хуанг, Ю., Лю, К., Метаксас, Д.Н.: Сегментация видеообъектов с помощью гиперграфа. В: CVPR (2009 г.)

Икизлер, Н., Форсайт, Д.: Поиск сложной человеческой деятельности без наглядных примеров. IJCV 80(3) (2008 г.)

Икизлер-Синбис, Н., Синбис, Р.Г., Скларофф, С.: Обучение действиям в Интернете. В: ICCV (2009 г.)

Джуанг, Х., Серр, Т., Вольф, Л., Поджио, Т.: Биологическая система распознавания действий. В: ICCV (2007 г.)

Ке, Ю., Суктанкар, Р., Хеберт, М.: Обнаружение событий в многолюдных видео. В: ICCV (2007 г.)

Лаптев, И., Маршалек, М., Шмид, К., Розенфельд, Б.: Изучение реалистичных действий человека по фильмам. В: CVPR (2008 г.)

Лью, Ф., Глейхер, М.: Изучение цвета и признаков местоположения для обнаружения и сегментации движущихся объектов. В: CVPR (2009 г.)

Лю Дж., Луо Дж., Шах М.: Распознавание реалистичных действий на видео «в дикой природе». В: CVPR (2009 г.)

Марон, О., Ратан, А.Л.: Обучение с несколькими экземплярами для классификации естественных сцен. В: ICML, стр. 341–349 (1998)

Маршалек М., Лаптев И., Шмид К.: Действия в контексте. В: CVPR (2009 г.)

Миколайчик, К., Уэмура, Х.: Распознавание действий с помощью словарного леса движения и внешнего вида. В: CVPR (2008 г.)

Мур, Д. Дж., Эсса, И., Хейс, М. Х.: Использование действий человека и контекста объекта для задач распознавания. В: ICCV (1999)

Ниблес Дж. К., Хан Б., Ференц А., Фей-Фей Л.: Извлечение движущихся людей из интернет-видео. В: Форсайт Д., Торр П., Зиссерман А. (ред.) ECCV 2008, часть IV. LNCS, том. 5305, стр. 527–540. Спрингер, Гейдельберг (2008 г.)

Олива, А., Торральба, А.: Моделирование формы сцены: целостное представление пространственной оболочки. IJCV 42(3), 142–175 (2001)

Шульдт, К., Лаптев, И., Капуто, Б.: Распознавание человеческих действий: локальный подход SVM. В: МКЗР (2004 г.)

Тран, Д., Сорокин, А.: Распознавание человеческой деятельности с метрическим обучением. В: Forsyth, D., Torr, P., Zisserman, A. (eds.) ECCV 2008, Part I. LNCS, vol. 5302, стр. 548–561. Спрингер, Гейдельберг (2008 г.)

Виджаянарасимхан, С., Грауман, К.: Ключевые слова для визуальных категорий: обучение с несколькими экземплярами для категоризации объектов со слабым контролем. В: CVPR (2008 г.)

Информация об авторе

Принадлежности

Кафедра компьютерных наук, Бостонский университет,

Назли Икизлер-Синбис и Стэн Скларофф

Вы также можете искать этого автора в PubMed Google Scholar

Вы также можете искать этого автора в PubMed Google Scholar

Права и разрешения

Информация об авторских правах

© 2010 Springer-Verlag Berlin Heidelberg

Об этой статье

Процитировать эту статью

Скачать цитату

Название издателя: Springer, Berlin, Heidelberg

Поделиться этой статьей

Все, с кем вы поделитесь следующей ссылкой, смогут прочитать этот контент:

Я читал, что объекты содержат действия, которые они могут выполнять, как функции, а их атрибуты — как переменные.Но меня смущают объекты, которые, кажется, не выполняют никаких действий, таких как целое число, дерево квадрантов и множество.

Я знаю, что мы можем представить эти "нереальные объекты" как абстрактные типы данных. Но это отличается от первоначального определения, потому что функции теперь работают с объектом.

Например, вот два "настоящих" класса Furnace и Resource и "абстрактный" класс Integer. Печь и ресурс выполняют определенные функции, а целое число управляется функциями. Какой способ создания классов правильный?

Я думаю, что на этом этапе обучения вам лучше забыть о любом абстрактном классе с именем NSInteger, потому что он в лучшем случае запутает вас, а в худшем — полностью введет в заблуждение. Подождите, пока у вас не появится какая-то мысленная структура, в которую вы сможете вставлять вещи, и они обретут смысл.

1 Ответ 1

Во-первых, давайте посмотрим, что на самом деле означает "объектно-ориентированный".

Самым первым объектно-ориентированным языком программирования был Simula (1960 г.). Как следует из названия, он был разработан для моделирования. Если вы хотите иметь возможность имитировать объекты таким образом, чтобы они были неотличимы от реальных вещей, одно важное требование состоит в том, что вы можете наблюдать только внешне видимое поведение. Если бы вы могли наблюдать за его внутренним поведением или его внутренним представлением, вы могли бы отличить симуляцию от симуляции, чего мы хотим избежать.

Следовательно, абстракция данных и инкапсуляция являются фундаментальными для объектно-ориентированного программирования. И не какую-либо абстракцию данных, мы говорим конкретно об процедурной или поведенческой абстракции. Это отличается от той абстракции, которую используют абстрактные типы данных. (См., например, Понимание абстракции данных, пересмотренное Уильяма Р. Кука для простого объяснения)

Термин "объектно-ориентированный" придумал Алан Кей, разработчик Smalltalk (помимо многих других вещей). Он определил ООП следующим образом:

ООП для меня означает только обмен сообщениями, локальное хранение, защиту и сокрытие процесса состояния, а также чрезвычайно позднее связывание всех вещей.

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

Просто мягкое напоминание о том, что на последнем OOPSLA я приложил некоторые усилия, чтобы попытаться напомнить всем, что Smalltalk - это не только НЕ его синтаксис или библиотека классов, это даже не классы. Мне очень жаль, что я давно придумал термин "объекты" для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее.

Большая идея - "обмен сообщениями" - это то, что ядро о Smalltalk/Squeak (и это то, что так и не было полностью завершено на этапе Xerox PARC). У японцев есть маленькое слово — ma — для «того, что находится между ними» — возможно, ближайший английский эквивалент — «интерстициальный». Ключом к созданию отличных и растущих систем гораздо больше является разработка того, как взаимодействуют ее модули, а не то, какими должны быть их внутренние свойства и поведение. Подумайте об Интернете — чтобы жить, он (а) должен допускать множество различных видов идей и реализаций, выходящих за рамки какого-либо единого стандарта, и (б) обеспечивать различные степени безопасного взаимодействия между этими идеями.

Обмен сообщениями является фундаментальным объектно-ориентированным подходом как в качестве метафоры, так и в качестве механизма.

Если вы отправляете кому-то сообщение, вы не знаете, что он с ним делает. Вы можете единственное наблюдать за их реакцией. Вы не знаете, обработали ли они сообщение сами (т.е. есть ли у объекта метод), переслали ли они сообщение кому-то другому (делегирование/проксирование), поняли ли они его вообще. Вот что такое инкапсуляция, вот что такое ООП. Вы даже не сможете отличить прокси от настоящего, пока он отвечает так, как вы ожидаете.

Алан Кей разработал Smalltalk примерно в то же время, когда были изобретены современные сети. Он работал в Xerox PARC, где был изобретен Ethernet, и знал некоторых людей, которые как раз находились в процессе изобретения того, что позже станет ARPANet, а затем и Интернетом. Он представлял объекты как крошечные маленькие компьютеры со своими собственными правами, со своей собственной памятью (переменные экземпляра), закрытым кодом (методами), и единственный способ поговорить с ними — послать им сообщение (точно так же, как вы не можете прочитать другое). памяти компьютера в Интернете или выполнить его код, но вы можете отправить ему сообщение):

С точки зрения компьютеров, Smalltalk представляет собой рекурсию самого понятия компьютера.Вместо того, чтобы делить «компьютерный материал» на вещи, каждая из которых менее сильна, чем целое — например, структуры данных, процедуры и функции, которые являются обычными атрибутами языков программирования, — каждый объект Smalltalk представляет собой рекурсию на все возможности компьютера. Таким образом, его семантика немного напоминает тысячи и тысячи компьютеров, соединенных вместе очень быстрой сетью. Таким образом, вопросы конкретного представления можно откладывать почти на неопределенный срок, потому что мы в основном озабочены тем, чтобы компьютеры вели себя надлежащим образом, и интересуются конкретными стратегиями только в том случае, если результаты неверны или возвращаются слишком медленно. —Ранняя история Smalltalk, Алан Кей

Вышеупомянутый Уильям Кук изучил множество языков программирования, которые, по общему мнению, являются объектно-ориентированными, и многие языки программирования, которые, по общему мнению, не являются объектно-ориентированными, и работал над определением того, точно, дело в том, что языки, которые обычно называют «объектно-ориентированными», имеют что-то общее и что отличает их от языков, которые, как принято считать, не являются объектно-ориентированными. И он обобщил свои выводы в Предложении по упрощенным современным определениям «объекта» и «объектно-ориентированного»:

Динамическая диспетчеризация операций является существенной характеристикой объектов. Это означает, что вызываемая операция является динамическим свойством самого объекта. Операции нельзя идентифицировать статически, и вообще нет никакого способа точно определить, какая операция будет выполнена в ответ на данный запрос, кроме как путем ее запуска. Это точно так же, как с функциями первого класса, которые всегда динамически отправляются.

Обратите внимание, что последнее предложение очень интересное. На самом деле Уильям Кук в шутку утверждал, что λ-исчисление — это первый объектно-ориентированный язык программирования, потому что единственным механизмом абстракции λ-исчисления являются функции, и, следовательно, вся абстракция всегда функциональна/поведенческая.

Вы спрашивали о целых числах, множествах и деревьях квадрантов, но давайте начнем с чего-то еще более простого: логических значений.

Вы, вероятно, знакомы с тем, как выглядит кодирование логических значений на основе Абстрактного типа данных: в основном это всего лишь один бит и некоторые функции (или операторы), которые смотрят на значение этого бита. Но, как мы обсуждали выше, это невозможно для объектов: вы не можете проверить внутреннее представление, поэтому вы не можете знать, какое значение имеет бит.

Давайте вернемся к λ-исчислению и, в частности, к Черч-кодированию булевых значений. Кодировка Черча кодирует логические значения как функции (очевидно, поскольку функции — это единственное, что существует в λ-исчислении), а именно как пару функций, определяемых примерно так:

[Примечание: все примеры кода будут на ECMAScript, с которым я знаком гораздо лучше, чем с C++, но в них нет ничего специфичного для ECMAScript, за исключением некоторых элементов синтаксиса. Все концепции являются общими объектно-ориентированными концепциями, применимыми ко всем объектно-ориентированным языкам. Даже примеры, в которых используются классы, могут быть выражены с помощью трейтов, примесей или делегирования прототипов.]

Итак, по сути, у нас есть две функции с двумя параметрами, и первая вычисляет свой первый аргумент и игнорирует второй, а вторая вычисляет второй аргумент и игнорирует первый.

Другими словами, это условие!

Но подождите: здесь у нас есть «вещь» (истинная или ложная), которая является одновременно и ценностью, и поведением. Что это нам напоминает? Разве это не просто объект?

Действительно, объектно-ориентированное кодирование логических значений очень похоже на кодирование Черча, оно выглядит примерно так:

Вы упомянули множества: в статье Об абстракции данных, о которой я упоминал выше, на самом деле множества используются в качестве рабочего примера, чтобы показать, как будет выглядеть объектно-ориентированный набор и чем он отличается от АТД.< /p>

Главный вопрос заключается в следующем: если объекты поведенчески абстрактны, то каково поведение заданного объекта? Обратимся к математике. В математике обычно есть два способа определения множеств. Один из способов - просто перечислить всех участников, например. <1, 2, 3>. Однако перечисление всех членов «несколько неудобно», например, для набора всех четных целых чисел: вам потребуется много времени, чтобы записать все четные целые числа!

Итак, другой способ определения множеств в математике – это так называемая индикаторная функция. т.е. вы можете определить набор всех четных целых чисел как "member(2n) = true, member(2n+1) = false".

А теперь самое интересное: в типе данных набора на основе ADT набор, вероятно, имеет функцию contains. Но, как мы видели, в некотором смысле множество также является содержащей его функцией. И именно так вы можете представить набор объектно-ориентированным способом с поведенческой абстракцией: вы идентифицируете набор с помощью его индикаторной функции.(Например, в Scala Set[T] буквально является подклассом Function1[T, Boolean].)

Набор OO будет выглядеть примерно так:

Обратите внимание, что в зависимости от языка и библиотеки наборы могут реализовываться именно так, а могут и не так в вашем конкретном случае. На самом деле вполне вероятно, что наборы не реализуются в вашем конкретном случае. Гораздо более вероятно, что любой набор, с которым вы когда-либо столкнетесь, будет реализован как абстрактный тип данных, а не как объект. Но вы конкретно спросили, как можно реализовать такие вещи, как наборы, как объект с поведением, и это один из способов сделать это.

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

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

В частности, Объекты по определению не поддерживают то, что Уильям Кук называет "сложными операциями", под которыми он понимает операции, требующие проверки внутреннего представления более чем одного объекта одновременно. Помните, что объекты могут наблюдать друг за другом, только отправляя сообщения и наблюдая за ответом. Это означает, что один объект никогда не может проверять внутреннее представление другого объекта, даже если оба объекта являются экземплярами одного и того же типа/класса.

С АТД дело обстоит иначе: экземпляр АТД может проверять внутреннее представление другого экземпляра того же АТД.

Простым примером сложной операции, которая тривиальна для АТД, но невозможна для объектов, является объединение двух двусвязных списков за время O(1). Для этого требуется одновременный доступ к указателю prev головы второго списка и указателю next хвоста первого списка, что разрешено для АТД, но невозможно для объектов.

Итак, ни один из двух вариантов не является более правильным, чем другой. И нет ничего плохого в том, например. Целые числа C++ или экземпляры классов Java являются АТД, а не объектами.

Читайте также: