Инкапсуляция

ОБЪЕКТ

ООП

Итак, в чем же основные преимущества ООП, почему оно стало таким популярным?

Как ни странно, но трудно ответить на этот вопрос не объяснив базовых понятий. Уверен, что усвоив базовые понятия ООП, вы сами без труда ответите на этот вопрос.

Несмотря на то, что в различных источниках делается акцент на те или иные особенности внедрения и применения ООП, 3 основных (базовых) понятия ООП остаются неизменными. К ним относятся:

· Наследование (Inheritance)

· Инкапсуляция (Encapsulation)

· Полиморфизм (Polymorphism)

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

А для начала рассмотрим пару мнений, которые в какой-то степени помогут Вам прояснить сложившуюся вокруг поставленного вопроса ситуацию.

Итак, первое из них имеет некоторый академический оттенок:

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

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

Не очень понятно? Тогда попробуем зайти с другой стороны и упростим описание. Начнем с общеизвестного примера.

Вы сидите за обеденным столом и вам понадобилась соль, которая находится на другом конце стола и вы не можете до нее дотянуться. Обидно, но чтобы не оставаться без соли Вы просите своего друга передать Вам соль. Ура! Вы получили то, что хотели.

Что Вы сделали для того, чтобы получить соль? Просто сказали: "Передай мне, пожалуйста, соль".

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

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

Так в чем же принципиальная разница?

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

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

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

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

Название "Объектно-ориентированное программирование" говорит само за себя. Центром внимания ООП является объект.

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

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

А теперь рассмотрим формальное определение объекта в ООП:

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

Объект состоит из следующих трех частей:

· имя объекта;

· состояние (переменные состояния);

· методы (операции).

Не правда ли, очень похоже? Мы только не указали, что объект должен иметь имя. Но, как Вы сами понимаете, нам это необходимо для идентификации конкретного объекта. Впрочем, практически все физические объекты мы как-либо уникально идентифицируем. Иначе, как мы разберемся где есть какой объект?

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

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

Класс (class) - это группа данных и методов(функций) для работы с этими данными. Это шаблон. Объекты с одинаковыми свойствами, то есть с одинаковыми наборами переменных состояния и методов, образуют класс.

Объект (object)- это конкретная реализация, экземпляр класса. В программировании отношения объекта и класса можно сравнить с описанием переменной, где сама переменная(объект) является экземпляром какого-либо типа данных(класса).

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

Методы (methods)- это функции(процедуры), принадлежащие классу.

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

Инкапсуляция является одним из ключевых понятий ООП.Для начала приведу формальное определение этого понятия:

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

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

Можно сказать, что инкапсуляция подразумевает под собой скрытие данных (data hiding), что позволяет защитить эти данные.

А теперь определение, которое, как мне кажется, наиболее точно определяет суть инкапсуляции:

Переменные состояния объекта скрыты от внешнего мира. Изменение состояния объекта (его переменных) возможно ТОЛЬКО с помощью его методов(операций).

Почему же это так важно? Этот принцип позволяет защитить переменные состояния объекта от неправильного их использования.

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

Для иллюстрации приведенного выше постулата рассмотрим простой жизненный пример.

Представьте, что у Вас не заводится машина и Вы, увы, не механик и плохо разбираетесь в машинах. Вы открываете капот и начинаете выдергивать какие-то шланги, что-то окручивать. и т.д. Хорошо, если Вы запомнили что, где и как выдергивали и откручивали. А если нет? Или, у Вас стрелка уровня топлива стоит на нуле, а Вы считаете, что у Вас полно топлива и полезете со спичками внутрь бензобака проверять уровень топлива. Какие последствия Вас могут ожидать? В лучшем случае Вы и Ваша машина останутся живы, если Вам о-о-очень повезет.

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

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

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

В ООП мы это правило определяем как закон: "Объект не приемлет дилетантов. Только 'специалисты' могут как-либо изменять состояние объекта." И это правильно!

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

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

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

Я думаю, что здесь же стоит упомянуть еще одно понятие ООП. Это абстрактные типы данных (ABSTRACT DATA TYPES). Абстрактный тип данных - это группа тесно связанных между собой данных и методов(функций), которые могут осуществлять операции над этими данными.

Поскольку подразумевается, что эта структура защищена от внешнего влияния, то она считается инкапсулированной структурой. Важным же отличием от других аналогичных структур является то, что данные заключенные в этой структуре, тесно связанны и активно взаимодействуют между собой внутри структуры. Подобные структуры имеют слабые связи с внешним миром посредством ограниченного интерфейса. Суть подобных структур довольно проста: данные имеют тесные взаимосвязи внутри структуры, но слабые связи с внешним миром посредством ограниченного числа методов. Таким образом, структуры подобного рода имеют достаточно простой, но эффективный интерфейс, что позволяет их легко интегрировать в программах. Проведем аналогию. Рассмотрим монитор как единый объект. Я думаю, на много приятнее иметь дело с несколькими кнопками на Вашем мониторе для того, чтобы его настроить, чем копаться в его внутренностях, пытаясь его настроить. Для того, чтобы настроить монитор необходимо знать только простой интерфейс настройки и все. А для его подключения к компьютеру достаточно только подключить интерфейсный кабель. Просто, удобно, доступно (звучит как рекламный ролик)!


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



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