Файл: Основные понятия объектно- ориентированного программирования.pdf
Добавлен: 04.04.2023
Просмотров: 155
Скачиваний: 2
2.5 Объект
Понятие объекта использовалось человеком с древнейших времен: еще античные греки высказывали идею о том, что мир можно трактовать в категориях и объектов, и событий. В XVII веке Рене Декарт замечал, что человечество рассматривает вселенную с объектно-ориентированной точки зрения, где объект — это модель окружающей действительности, существующей во времени и пространстве. В компьютерной технике понятие «объект» стало применяться при разработке компьютеров, отходящих от фон-неймановской архитектуры, дабы проложить границу между высоким уровнем программного продукта и низким уровнем вычислительной машины.[41]
Программирование с использованием объектов является проекцией построения объектов фактически существующего мира. Новый проект начинается не с постановки задачи, которую необходимо решить, а с детального исследования параметров реального мира, которые помогут в решении этой задачи. Когда параметры и их носители — объекты — проанализированы и описаны, можно приступать непосредственно к решению первоначальной задачи.[42]
Объекты — это своеобразные строительные блоки программы, каждый цельный код по сути является набором объектов. Это одно из двух фундаментальных понятий объектно-ориентированного программирования, давшее название всей концепции.[43] Под объектом мы обычно понимаем некую сущность (материальную или абстрактную) предметной области, обладающую определенным набором атрибутов (состоянием) и поведением.
Поведение описывает способ, с помощью которого объект реагирует на воздействия извне и реализуется в виде подпрограмм (методов), вызываемых в ответ на полученное сообщение. Разные объекты используют различные методы, отвечая на одно и то же сообщение. Поведение диктуется классом, к которому принадлежит объект. Таким образом, все экземпляры, принадлежащие к одному классу, имеют идентичное поведение, то есть вызывают одни и те же методы в ответ на одинаковые запросы.
Объект может не только изменять свое собственное состояние, но и воздействовать на другие объекты: взаимодействие осуществляется путем обмена сообщениями. Совокупность сообщений, понимаемых объектом, называется его интерфейсом. Чтобы программа полноценно функционировала, необходимо, чтобы все объекты в её составе имели максимально полные, но в то же время простые интерфейсы.[44]
Так, например, языки C++/CLI и C# описывают интерфейс как совокупность функций, свойств и событий, в языке Java интерфейс место событий занимают статические переменные. Интерфейсы тесно связаны с классами: будучи наследованным, интерфейс обязывает классы подчиняться установленным им правилам поведения. Таким образом, объекты, созданные из разных классов, наследующих идентичный интерфейс, в определённых ситуациях будут вести себя одинаково. В отличие от классов из интерфейсов невозможно создать объекты, для этого они не предназначены. Их главное назначение заключается в формировании поведения объектов путём навязывания классу объекта обязательной реализации функций, свойств и событий, указанных в интерфейсе.[45]
Осуществлять обращение к объекту может любой другой объект системы. Он должен отправить предписание (просьбу, приказ, требование) для выполнения некоторых действий. Если выполнение предписания объектом-получателем возможно, то оно осуществляется, а объекту-отправителю может возвращаться некоторый объект. Если предписание не может быть выполнено, получатель в какой-либо форме информирует об этом отправителя или систему времени выполнения.[46]
За исключением языков вроде Lua и JavaScript, где отсутствует понятие «класс», в подавляющем большинстве объектно-ориентированных языков (Java, C++, C#), все объекты являются экземплярами определенного класса. Именно в классе прописана вся необходимая для построения объекта информация, даже объём памяти, необходимый для его хранения. Сам объект хранится в системе в виде характеристик всех его полей и ссылок на методы класса, к которому он принадлежит. А вот в языке программирования Python объектами являются все возможные значения, даже классы. Другими словами, мы может создать метакласс, экземплярами которого будут другие классы.[47]
Объекты создаются при помощи конструктора класса, а уничтожаются с помощью деструктора (C++), сборщика мусора (Java и C#), или с использованием счетчика ссылок на объект и сообщения («dealloc» в Objective-C). Назначение конструктора состоит в инициализации значений данных нового объекта, а его имя совпадает с именем класса. При создании объекта обычно используется тот конструктор, параметры которого смогут обеспечить требуемые начальные значения данных объекта.[48] В С++ каждый класс должен иметь хотя бы один конструктор, но обычно их несколько. Конструктор создает «пустой» объект, распределяя память для размещения его переменных, и заполняет его, определяя, какими значениями эти переменные будут обладать. «Конструктор по умолчанию» вызывается в случае, если конструктор не был создан вручную, он не имеет параметров и не может инициализировать объекты. «Конструктор копии» имеет один единственный параметр-константу или ссылку на объект данного класса и позволяет инициализировать новый объект значением уже существующего. «Конструктор преобразования типа» также имеет один параметр, тип которого не совпадает с тем, что задан конструктором, и инициализирует новый объект другого типа, заданного в параметре.[49]
Деструктор — это функция класса, существующая для уничтожения ранее созданного объекта. Деструктор вызывается, по умолчанию, когда объект выходит из области видимости или удаляется.[50] Освобождая память, используемую объектом, он уничтожает все результаты работы конструктора. В С++ имя деструктора совпадает с именем класса с предшествующим символом "~". Тело деструктора обычно не содержит данных, за исключением случаев, когда конструктор распределил память для переменных с помощью оператора new: в этом случае в тело деструктора должен помещаться оператор delete, освобождающий память.
2.6 Класс
В ООП термин «класс» применяется для описания ряда объектов, имеющих похожее поведение. Все индивидуальные представители класса именуются его экземплярами. Стоит заметить, что поведение ассоциируется именно с классом, а не с его индивидуальными представителями. Таким образом, все экземпляры класса одинаково воспринимают сходные команды и выполняют их идентичным способом.[51]
Класс — это некий шаблон, своеобразный «чертеж», описывающий объекты определенной структуры и поведения и определяющий механизмы создания экземпляра класса. Посредством переменных класс описывает структуру объекта, посредством методов — его поведение. Таким образом, методы и переменные прописаны в классе, в то время как индивидуальные значения переменных определены в экземпляре.[52] Попытка объяснить взаимосвязь классов и объектов напоминает стремление разрешить извечную дилемму о яйце и курице. В данном случае можно сказать, что первым все-таки был именно класс, так как без него объект не может появиться.[53]
Каждый объект является «экземпляром» определенного класса, однако в разных языках могут существовать дополнительные типы данных (числа, массивы, указатели), экземпляры которых не являются объектами. В объектно-ориентированных языках все переменные, константы, методы, процедуры и функции, могут или должны принадлежать какому-нибудь классу, сам же класс — это список полей (свойств) и методов (функций).
Классы способны задавать переменные — обычные или статические. Статические переменные существуют в одном экземпляре на всю программу, а обычные создаются по одной копии для каждого экземпляра класса. Методы также могут быть отнесены либо к классу, либо к его экземплярам. Статический метод вызывается сам по себе, обычный метод вызывается только у конкретного объекта. В некоторых языках программирования имеют место «абстрактные» классы, в описание которых входят и поля, и методы, однако создание новых объектов (экземпляров класса) возможно только из неабстрактных.
С классом тесно связано понятие интерфейса, иначе говоря, все возможные операции, которые может выполнить некая часть программы. Описание интерфейса включает перечень и порядок аргументов, передаваемых на вход алгоритмам, а также возвращаемое значение. Значительно расширяет интерфейсы и классы механизм наследования: наследованный класс или интерфейс вбирает в себя все характеристики и параметры родителей.[54]
Вот как будет выглядеть создание нового класса в языке С++:
class Имя класса
{
Раздел атрибутов;
Раздел операций
}
Как только определен новый класс, можно переходить к созданию его переменных, иначе говоря, экземпляров. Для объявления переменных класса предназначен раздел атрибутов. В нем задается все множество возможных значений (состояний) объектов класса.
Раздел операций нужен для объявления и определения операций (методов), которые можно будет выполнить над объектами класса или выполняемых самими объектами. Методы описывают поведение объекта в результате выполнения операции. Объявление и определение осуществляется отдельно.
В С++ переменную называют элемент-данное, а метод — элемент - функция, так как реализация метода представляет собой функцию в обычном понимании этого слова. В других языках программирования, например в Delphi, метод может быть представлен процедурой.[55]
Чтобы каждый раз заново не разрабатывать похожие классы, существуют созданные профессиональными программистами библиотеки классов стандартных объектов. Имея в наличии подходящую библиотеку классов, достаточно добавить её в файл программы, выбрать необходимый класс и создать из него нужное количество объектов с требуемыми значениями. Библиотеки значительно ускоряют написание программ, увеличивают их надёжность, так как создаются из неоднократно проверенных и отлаженных классов. Наиболее известны и популярны среди программистов такие библиотеки классов как STL, MFC, ATL, .NET Framework Class Library, java.lang, java.util,java.io и другие.[56]
Глава 3. Объектно-ориентированные языки программирования
Стоит заметить, что не все языки программирования являются объектно-ориентированными в строгом понимании этого слова. Так язык Pascal способен с помощью типа Record создавать объекты и классы, что все же не делает его объектно-ориентированным. Как правило, язык программирования относят к объектно-ориентированным только при выполнении определенных условий.
Главный признак причисления языка к семейству объектно-ориентированных — это понятие объекта как абстракции данных и присутствие интерфейса в виде именованных операций и собственных данных с ограничением доступа к ним. При этом объекты должны принадлежат соответствующим классам, а классы наследовать свойства суперклассов.[57]
Все языки, так или иначе использующие объектно-ориентированный стиль программирования, можно классифицировать следующим образом:
1. объектные (Smalltalk, Simula-67, Java, C#). Эти языки наиболее строго следуют объектной парадигме;
2. объектно-ориентированные (С++, Object Pascal Objective-C). Для языков данной группы ООП является приоритетным подходом, но не единственно возможным;
3. смешанные с поддержкой ООП (Common Lisp с CLOS, Clojure). В этих языках объектный подход реализуется посредством использования библиотек и расширений.
Языки каждой из групп обладают своими неоспоримыми достоинствами. Например, Smalltalk, наиболее наглядно представляющий объектную парадигму, не нашел широкого применения из-за проблем с быстродействием. Язык Java перегружен тяжелыми синтаксическими конструкциями и ориентирован главным образом на кроссплатформенные приложения. C#, во многом копирующий Java, имеет неплохие перспективы, но его распространение затрудняется ориентированностью лишь на продукцию Microsoft. Объектно-ориентированный С++ получил наибольшую популярность в образовательной среде, несмотря на свой главный недостаток - объём и количество библиотечных средств. Третья группа языков, уходящая корнями в Lisp-традиции, могла бы считаться наиболее перспективной для изучения, если бы не низкая востребованность Lisp-специалистов на рынке труда.
В настоящее время наиболее популярными языками объектно-ориентированного программирования являются С++, Java и C#, из них C++ употребляется наиболее широко.[58] Java уступает ему первое место, так как лишен столь важных компонентов, как указатели, шаблоны и множественное наследование, что делает его гораздо менее мощным и гибким. Другие объектно-ориентированные языки, например, С#, тоже успешно развиваются, однако также уступают по распространению C++.[59]
Глава 4. Плюсы и минусы ООП
Успех ООП можно объяснить множеством факторов, среди которых можно назвать даже такие как поддержка крупными корпорациями и принудительная популяризация. Но, не стоит забывать, что именно объектно-ориентированный подход смог дать ответы на давно стоявшие практические вопросы написания и организации программ.[60]