double arrow

Принципы объектно-ориентированного программирования

Все объектно-ориентированные языки используют три базовых принципа объектно-ориентированного программирования:

  • Инкапсуляция. Как данный язык скрывает внутренние особенности реализации объекта?
  • Наследование. Как данный язык обеспечивает возможность многократного использования программного кода?
  • Полиморфизм. Как данный язык позволяет интерпретировать родственные объекты унифицированным образом?

Первым принципом ООП является инкапсуляция. Инкапсуляция – это механизм программирования, связывающий воедино код и данные, которыми он манипулирует, ограждающий их от внешнего доступа и неправильного применения и скрывающий средствами языка детали реализации. Например, предположим, что мы используем класс представляющий объекты типа пера (Pen). Такой класс инкапсулирует внутренние способности объектов рисовать точки, линии и фигуры разной толщины и цвета. Принцип инкапсуляции позволяет упростить задачу программирования в том смысле, что уже нет необходимости беспокоится о многочисленных строках программного кода, который выполняет работу класса пера "за кулисами". Все, что требуется, так - это создание экземпляра класса пера и взаимодействовать с ним путем обращения к его функциям.

Одним из важных аспектов инкапсуляции является защита данных. В идеале данные, характеризующие состояние объекта, должны определяться, как закрытые и недоступные для внешнего окружения. В этом случае внешнее окружение объекта будет вынуждено запрашивать право на изменение или чтение соответствующих значений. Таким образом, понятие инкапсуляции отражает общее правило, согласно которому поля данных объекта не должны быть непосредственно доступны из открытого интерфейса. Если пользователю необходимо изменить состояние объекта, то он должен сделать это не напрямую, а косвенно, с помощью функций чтения (get()) и модификации (set()). В С# доступность данных реализуется на уровне синтаксиса с помощью ключевых слов public, private, protected, и protected internal.

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

Следующим принципом ООП является наследование, означающее способность языка обеспечить построение определений новых классов на основе определений уже существующих классов. В сущности, наследование позволяет расширить возможности поведения базового класса (называемого также родительским классом) с помощью построения подкласса (называемого производным или дочерним классом), наследующего характеристики и функциональные возможности родительского класса. По сути дела такая форма наследования представляет собой повторное использование программного кода одного (базового) класса в других (производных от него) классах. Как правило, в этом случае дочерний класс расширяет возможности базового класса, добавляя к ним некоторые новые возможности, отсутствующие в базовом классе. Такая форма наследования получила название "is-a" (т.е. быть тем же самым, но с более широкими возможностями).

Существует и другая форма многократного использования программного кода – это модель локализации/делегирования (также известная, как отношение локализации "has-a"). Эта форма не используется для создания отношений "класс-подкласс". Вместо этого класс может определить в своем составе некоторую переменную другого класса и открыть часть или все ее функциональные возможности для внешнего окружения. В этом случае класс больше похож на контейнер, в котором содержатся экземпляры других классов.

Третьим принципом ООП является полиморфизм. Он характеризует способность языка одинаково интерпретировать родственные объекты. Эта особенность объектно-ориентированного языка позволяет базовому классу определить множество членов для всех производных классов. Формально это общее членов называют полиморфным интерфейсом. Полиморфный интерфейс для класса строится с помощью определения некоторого произвольного числа виртуальных и абстрактных функций. Виртуальную функцию класса можно изменить в производном классе, а абстрактную функцию можно только переопределить. Когда производные классы переопределяют функции, определенные в базовом классе, то они, по существу, переопределяют свою реакцию на соответствующий запрос. Кроме возможности переопределения функций язык С# предоставляет возможность использовать другую форму полиморфизма – перегрузку функций. Перегрузку следует рассматривать, как дополнительную возможность различать функции с одинаковым названием, отличающихся разным количеством или типом аргументов. Поэтому перегрузку можно применять не только к функциям – членам класса, но и к глобальным функциям.


Сейчас читают про: