Файл: История и развитие методологии объектно-ориентированного программирования.pdf
Добавлен: 29.03.2023
Просмотров: 227
Скачиваний: 2
СОДЕРЖАНИЕ
Глава 1. «История и развитие методологии объектно-ориентированного программирования»
Основные принципы структурной методологии
Глава 2 «Определения и основные понятия объектно-ориентированное программирование»
Глава 3 «Объектно-ориентированные языки программирования и их применение»
В обыденной жизни люди используют (пусть даже неосознанно) различные приемы “экономии мышления”, позволяющие осмысливать и выражать сложные явления в простых понятиях. Типичными приемами “экономии мышления” являются:
· абстрагирование (отбрасывание несущественных деталей);
· обобщение (выделение общих существенных признаков у разных явлений или предметов);
· классификация (осознание связи между явлениями и степени их схожести).
Эти простые приемы помогают человеку справиться со сложностью рассматриваемых явлений. И объектно-ориентированные языки программирования также должны предоставлять подобные средства для “борьбы со сложностью” программ. Для реализации объектно-ориентированного подхода в языки программирования вводятся новые понятия:
Объекты — особые программные единицы, состоящие из данных и алгоритмов для обработки именно этих данных. Данные, входящие в состав объекта, называются полями (атрибутами, свойствами, членами). Алгоритмы, входящие в состав объекта, называются методами (сервисами, операциями, функциями-членами). К сожалению, единой устоявшейся терминологии в объектно-ориентированном программирование нет, и в разных языках используются различные термины для обозначения одних и тех же понятий.
Классы — это объектные типы данных. Подобно тому, как целые числа принадлежат какому-нибудь целочисленному типу (например, integer или byte), объекты также принадлежат какому-либо объектному типу — классу. Все объекты одного класса имеют одинаковый набор полей и одинаковый набор методов.
Классы и объекты — это отдельные, но тесно связанные понятия. В частности, каждый объект является экземпляром какого-либо класса; класс может порождать любое число объектов. В большинстве практических случаев классы статичны, то есть все их особенности и содержание определены в процессе компиляции программы. Из этого следует, что любой созданный объект относится к строго фиксированному классу. Сами объекты, напротив, в процессе выполнения программы создаются и уничтожаются.
В качестве примера рассмотрим классы и объекты для задачи управления воздушным движением. Наиболее важные абстракции в этой сфере - самолеты, графики полетов, маршрут и коридоры в воздушном пространстве. Трактовка этих классов объектов по самому их определению достаточно статична. Иначе невозможно было бы построить никакого приложения, использующего такие общепонятные факты, как то, что самолеты могут взлетать, летать и приземляться, а также что никакие два самолета не должны находиться одновременно в одной и той же точке.
Объекты же этих классов, напротив, динамичны. Набор маршрутов полетов сменяется не очень часто. Существенно быстрее изменяется множество самолетов, находящихся в полете. Частота, с которой самолеты занимают и покидают воздушные коридоры, еще выше. [2, с 111-112]
Полезность использования классов и объектов заключается в том, что проверка логического (смыслового) соответствия между данными и функциями для обработки данных становится тривиальной задачей и может быть в основном переложена на компилятор (компьютер) — теперь он сам может определить неверное использование данных.
Инкапсуляция (дословно — “сокрытие”) — контролируемое сокрытие информации о внутренней структуре класса. В классе могут быть поля и методы, используемые объектами исключительно для обеспечения своей работы (например, буфер в динамической памяти, файл с рабочими данными, методы для работы с этим файлом и т.п.). Изменять такие поля или вызывать методы извне объекта опасно — это может нарушить его рабочее состояние. Для обеспечения безопасности объектов подобные поля и методы можно скрыть — запретить обращение к ним извне.
С позиций “борьбы со сложностью” инкапсуляция позволяет переложить часть контроля за правильностью работы с объектами на компилятор (компьютер).
Различные объектно-ориентированные языки предлагают разные возможности по инкапсуляции полей и методов (от полного отсутствия и до автоматического сокрытия всех полей). В промышленных объектно-ориентированных языках, таких, как C++, Java, Delphi, Eiffel и т.д., предусмотрены три уровня инкапсуляции полей и методов:
· public — на обращение к публичным полям и методам объектов нет никаких ограничений;
· protected — прямое обращение к защищенным полям и методам возможно только из методов данного класса и методов дочерних классов;
· private — прямое обращение к приватным полям и методам возможно исключительно из методов данного класса.
Наследование — создание новых классов путем дописывания только отличий от уже существующих классов, опуская описания совпадающих элементов. При наследовании новый класс называется классом-потомком (производным, дочерним, подклассом), а исходный класс называется классом-предком (базовым, родительским, суперклассом).
Наследование сокращает размер программы за счет исключения повторных описаний. Все поля и методы, объявленные в классе-предке, автоматически переносятся в класс-потомок, и их принято называть унаследованными (inherited).
При необходимости любой родительский метод можно переопределить — т.е. назначить выполнение другого алгоритма в случае вызова одноименного метода класса-потомка.
Некоторые объектно-ориентированные языки поддерживают множественное наследование, при котором производный класс наследует все свойства и методы одновременно от нескольких классов. К сожалению, множественное наследование таит в себе немало логических конфликтных ситуаций, а его поддержка усложняет язык программирования, и особенно — компилятор. По этой причине во многих объектно-ориентированных языках множественное наследование просто запрещено, но его можно сымитировать.
Совокупность всех классов-предков и классов-потомков называется иерархией классов.
Наследование классов — центральное понятие объектно-ориентированного программирования, на нем прямо или косвенно базируются все остальные понятия и механизмы. Абсолютному большинству механизмов объектно-ориентированного программирования, чтобы проявить свои преимущества, требуется построение иерархий классов.
Полиморфизм (дословно — “многообразие форм”) — возможность использовать одно имя для нескольких методов (или функций), имеющих сходное назначение. Другая интерпретация — один метод (функция) может иметь несколько вариантов реализации; такой метод (функция) называется полиморфным. Подобно другим механизмам объектно-ориентированного программирования, полиморфизм является средством упрощения разработки сложных программ. Фактически полиморфизм отделяет понятие, что надо сделать, от того, как это надо делать.
Если провести аналогию с реальной жизнью, то полиморфизм соответствует обобщенным действиям. Например, глагол “музицировать” означает “играть на музыкальном инструменте”. Но на разных музыкальных инструментах играют по-разному. Термин один, а вариантов действия — много. Значит, “музицировать” — полиморфное действие. В объектно-ориентированном программирование действию “музицировать” соответствовал бы полиморфный метод, имеющий свои реализации для каждого класса музыкальных инструментов.
В объектно-ориентированном программирование есть два вида полиморфных методов — перегруженные и виртуальные.
Перегруженные методы предназначены для выполнения одинаковых по смыслу операций с данными разных типов. Они имеют одинаковые имена, но разные списки аргументов и/или тип возвращаемого значения.
Виртуальные методы предназначены для выполнения одинаковых по смыслу операций в объектах родственных, но не совпадающих классов. Виртуальные методы имеют одинаковые имена и прототипы. Их главная особенность — они всегда точно соответствуют реальному классу объекта.
Типичный пример перегруженных функций — функция SQR в Паскале. Она вычисляет квадрат числа, причем для целых аргументов результат будет также целым, а для вещественных — вещественным.
Достоинства виртуальных методов проявляются только при использовании иерархии классов. Типичная схема использования виртуальных методов такова:
· В классе-предке иерархии объявляется полиморфный метод, который описывает некое полезное действие. При этом либо он использует виртуальный метод, либо сам является виртуальным.
· В классах-потомках соответствующий виртуальный метод переопределяется — для каждого класса-потомка это полезное действие выполняется по-своему.
· При вызове для объекта, принадлежащего классу-потомку, полиморфного метода на деле используется виртуальный метод класса-потомка (а не класса-предка).
Яркий пример подобного использования виртуальных методов — система графического оконного интерфейса Delphi или Visual Basic: каждый видимый элемент графического интерфейса — кнопка, ползунок, окно и т.п. — должен быть потомком класса TControl. В классе TControl вводятся общие полиморфные методы отрисовки элементов графического интерфейса, а любой его потомок может нарисовать себя на экране своим собственным способом. [4 ]
Определение Гради Буча гласит: «Объектно-ориентированное программирование – это методология программирования, которая основана на представлении программы в виде совокупности объектов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию на принципах наследуемости».
В данном определении можно выделить три части:
- Объектно-ориентированное программирование использует в качестве базовых элементов объекты, а не алгоритмы.
- Каждый объект является экземпляром какого-либо определенного класса.
- Классы организованы иерархически.
Программа будет объектно-ориентированной только при соблюдении всех трех указанных требований. В частности, программирование, не основанное на иерархических отношениях, не относиться к объектно-ориентированному программированию, а называется программированием на основе абстрактных типов данных. [2, с. 39]
По мнению Алана Кэя, создателя языка Smalltalk, объектно-ориентированный подход заключается в следующем наборе основных принципов:
1. Всё является объектом.
2. Вычисления осуществляются путём взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие. Объекты взаимодействуют, посылая и получая сообщения. Сообщение — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия.
3. Каждый объект имеет независимую память, которая состоит из других объектов.
4. Каждый объект является представителем класса, который выражает общие свойства объектов (таких, как целые числа или списки).
5. В классе задаётся поведение (функциональность) объекта. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия.
6. Классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования. Память и поведение, связанное с экземплярами определённого класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве. [1 с. 20-21].
В центре объектно-ориентированного программирования находится объект. Объекту можно посылать сообщения, и он может на них реагировать, используя свои данные. Объект — это экземпляр класса. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией.
Любая программа в широком смысле может рассматриваться как модель (воспроизведение или отражение) части реального мира (внешней среды, предметной области). Различные образования реального мира могут быть определены единым термином: объекты. К ним относятся окружающие нас в быту предметы, технические устройства, сооружения, животные и, наконец, сами люди. Каждый объект характеризуется только присущим ему набором (множеством) параметров (свойств), а также множеством действий, которые может выполнить сам объект и которые могут быть выполнены над данным объектом другими объектами. Ко всем объектам реального мира может быть применена единая по смыслу функция классифицирования, результатом выполнения которой является разбиение объектов на группы по различным признакам, видам и свойствам. В связи с этим можно ввести в рассмотрение понятие классов (групп) объектов. Это понятие определяет множество различных свойств объектов и множество различных действий (операций) над ними. Любая схема (или система) классифицирования обычно строится по принципу от «общего» к «частному» и, как правило, имеет многоуровневую структуру отношений, в которой элементы высших ступеней порождают (производят) элементы низших уровней. Эти элементы имеют свои конкретные особенности и одновременно получают все основные свойства и действия, то есть «наследуют» их от элементов верхнего уровня. Например, реальный объект стол обладает множеством различных свойств, таких как тип (обеденный, книжный, кухонный), габариты, цвет, тип древесины и т.д. К нему применимы различные действия: стол можно изготовить, смонтировать (собрать), ремонтировать, передвигать, демонтировать и т.д. Очевидно, что конкретный стол, как объект реального мира, можно считать принадлежащим к классу столов, который определяет общие характеристики всех столов. В свою очередь класс столов можно считать порождением элемента верхнего уровня, а именно класса мебели, все свойства которого одновременно являются и свойствами класса столов. Это означает, что класс столов «наследует» свойства и действия класса мебели. Далее можно рассмотреть класс изделий, в который будет включен класс мебели. О классе изделий и классе мебели можно сделать такие же заключения, что и о классах мебели и столов.