§ 1. Концепция ООП в языке программирования

 

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

  1. Машинно-ориентированное программирование.
  2. Структурное программирование.
  3. Модульное программирование.
  4. Объектно-ориентированное программирование.

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

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

Ключевыми чертами объектно-ориентированного программирования являются: инкапсуляция, наследование и полиморфизм. Часто к ним добавляют абстрагирование (абстракцию).

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

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

Наследование – способ определения нового типа, при котором этот тип наследует элементы существующего (свойства и методы), модифицируя или расширяя их (пример 1.4).

Наследование представляет собой процесс, в ходе которого один объект приобретает свойства другого объекта. При наследовании основная функциональность родительского класса (предка) расширяется в производном подклассе, который называют дочерним классом (потомком). Создание объектов по принципу наследования порождает иерархическую структуру (пример 1.5). Если не пользоваться иерархиями, то для каждого объекта пришлось бы явно определять все его свойства. Благодаря наследованию достаточно определить у потомка лишь те свойства, которыми не обладал предок.

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

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

Полиморфизм позволяет решать схожие по смыслу проблемы разными способами.

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

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

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

В примере 1.7 перечислены плюсы и минусы ООП.

Пример 1.1. Описание этапов развития программирования.
  1. Программирование на машиноориентированном языке ассемблер позволяет работать на уровне аппаратных средств компьютера. Программист должен продумать размещение данных в памяти, эффективно использовать регистры процессора, обеспечить взаимодействие разрабатываемой программы с операционной системой.
  2. Поскольку многие этапы разработки программ на языке ассемблер приходилось повторять от программы к программе, то следующий этап развития программирования связан с появлением подпрограмм и развитием технологии структурного программирования, когда поставленная задача разбивается на независимые подзадачи, реализуемые с помощью подпрограмм.
  3. На следующем этапе развития группы подпрограмм стали объединять в программные модули. Подпрограммы внутри модуля используют одни и те же глобальные данные, которые на этом этапе развития становятся структурированными.
  4. Дальнейшее усложнение программ привело к тому, что данные и подпрограммы для их обработки стали объединять в единое целое. Это привело к созданию языков, использующих объектно-ориентированную технологию решения задач.

Пример 1.2. В компьютерной игре объектом может быть персонаж. Свойствами персонажа могут быть: раса, здоровье, сила, деньги, ловкость, скорость, координаты, очки рейтинга и др. В качестве методов могут выступать действия персонажа: движение, понятие, использование или бросок предмета, атака, лечение, разговор и др. Игрок, управляя персонажем может менять его состояние (увеличить или уменьшить здоровье, деньги; изменить координаты и др.). Активировав какое-то из действий, игрок вызывает определенный метод обработки данных. Если игрок атакует другого персонажа, то тем самым он активизирует другой объект со своими методами и свойствами.

 

Пример 1.3. Инкапсуляция (от лат. in capsule — в оболочке) — это заключение данных и функционала в оболочку. В объектно-ориентированном программировании в роли оболочки выступают классы. Они не только собирают данные и методы в одном месте, но и защищают их от вмешательства извне (сокрытие).

Для персонажа компьютерной игры все его характеристики и действия описываются в одном классе. Некоторые характеристики или действия могут быть скрытыми. Например, расу героя, после того как герой выбран, невозможно изменить. Или лечение, которое происходит с течением времени, недоступно для управления.

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

Пример 1.5. Возможная иерархия персонажей компьютерной игры:

Пример 1.6. У разных персонажей может быть такое действие, как движение. Однако гномы и драконы будут передвигаться по-разному, гномы должны обходить препятствия, а дракон может лететь по прямой. Метод, реализующий перемещение, будет называться одинаково, а реализовываться по-разному. Для игрока достаточно выбрать точку, в которую персонаж должен переместиться.

Первым языком программирования, в котором были предложены основные понятия, впоследствии сложившиеся в парадигму ООП, была Симула, но термин «объектная ориентированность» не использовался в контексте использования этого языка. В момент его появления в 1967 году в нём были предложены революционные идеи: объекты, классы, виртуальные методы и др. Новый взгляд на программирование предложили в 1970‑х годах Алан Кэй и Дэн Ингаллс в языке Smalltalk. Здесь понятие класса стало основообразующей идеей для всех остальных конструкций языка. Именно этот язык стал первым широко распространённым языком объектно-ориентированного программирования.

Пример 1.7. Плюсы и минусы ООП.

Плюсы:

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

Минусы:

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