Для чего придумали объектно-ориентированное программирование

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

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

  • инкапсуляция;
  • наследование;
  • полиморфизм.

Инкапсуляция данных (от «капсула») – это механизм, который объединяет данные и код, манипулирующий с этими данными, а также защищает и то, и другое от внешнего вмешательства или неправильного использования. В ООП код и данные могут быть объединены вместе (в так называемый «черный ящик») при создании объекта.
Внутри объекта коды и данные могут быть закрытыми или открытыми.
Закрытые коды или данные доступны только для других частей того же самого объекта и, соответственно, недоступны для тех частей программы, которые существуют вне объекта.
Открытые коды и данные, напротив, доступны для всех частей программы, в том числе и для других частей того же самого объекта.Наследование. Новый, или производный класс может быть определен на основе уже имеющегося, или базового класса.
При этом новый класс сохраняет все свойства старого: данные объекта базового класса включаются в данные объекта производного, а методы базового класса могут быть вызваны для объекта производного класса, причем они будут выполняться над данными включенного в него объекта базового класса.
Иначе говоря, новый класс наследует как данные старого класса, так и методы их обработки.
Если объект наследует свои свойства от одного родителя, то говорят об одиночном наследовании. Если объект наследует данные и методы от нескольких базовых классов, то говорят о множественном наследовании.
Пример наследования – определение структуры, отдельный член которой является ранее определенной структурой.Полиморфизм – это свойство, которое позволяет один и тот же идентификатор (одно и то же имя) использовать для решения двух и более схожих, но технически разных задач.
Целью полиморфизма, применительно к ООП, является использование одного имени для задания действий, общих для ряда классов объектов. Такой полиморфизм основывается на возможности включения в данные объекта также и информации о методах их обработки (в виде указателей на функции).
Будучи доступным в некоторой точке программы, объект , даже при отсутствии полной информации о его типе, всегда может корректно вызвать свойственные ему методы.Полиморфная функция – это семейство функций с одним и тем же именем, но выполняющие различные действия в зависимости от условий вызова.
Например, нахождение абсолютной величины в языке Си требует трех разных функций с разными именами:

123

int abs(int);long int labs(long int);double fabs(double);

Язык C++

Главное — в деталях. Что на самом деле даёт ООП?

Я уже более двух лет денно и нощно копаюсь в ООП. Прочитал толстую стопку книг, потратил человеко-месяцы на рефакторинг кода с процедурного стиля в объектно-ориентированный и обратно. Друг говорит, что я заработал ООП головного мозга. Но есть ли у меня уверенность, что я умею решать сложные задачи и писать понятный код?
Я завидую людям, которые умеют уверенно пропихивать свое бредовое мнение. Особенно, когда это касается разработки, архитектуры. В общем того, к чему я страстно стремлюсь, но в чём испытываю бесконечные сомнения. Потому что я не гений, и не ФП-шник, у меня нет истории успеха. Но позвольте вставить 5 копеек.

Инкапсуляция, полиморфизм, объектное мышление…?

Любите, когда вас грузят терминами? Я прочитал достаточно, но слова выше до сих пор не говорят мне ни о чем конкретном. Я привык объяснять вещи на понятном мне языке. Уровне абстракции, если хотите. И давно хотел знать ответ на простой вопрос: «Что даёт ООП?». Желательно с примерами кода. И сегодня я попробую ответить на него сам.

3 Что учить дальше?

Мы разобрали ценности и знаем к чему стоит стремиться, кроме того, мы поверхностно посмотрели на механизмы, которые предоставляет нам объектно-ориентированное программирование, не фокусируясь на каком-либо определенном языке

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

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

3.1 Список использованных источников

  1. Рейтинг популярности языков программирования TIOBE. URL: https://tiobe.com/tiobe-index/
  2. SOLID принципы. Рефакторинг. URL: https://pro-prof.com/archives/1914
  3. Почему мне кажется, что студентов учат ООП неправильно. URL: https://habr.com/ru/post/345658/
  4. C++ Russia 2018: Фёдор Короткий, Память – идеальная абстракция. URL: https://vk.com/wall-105242702_701
  5. Мейер Б. Объектно-ориентированное конструирование программных систем. М.: Издательско-торговый дом «Русская Редакция», «Интернет-университет информационных технологий», 2005. 1232 с.: ил.
  6. Мартин Р. Чистый код. Создание, анализ и рефакторинг. Библиотека программиста. – СПб.: Питер, 2014. – 464 с.
  7. Джейсон Мак-Колм Смит Элементарные шаблоны проектирования : Пер. с англ. — М. : ООО “И.Д. Вильямс”, 2013. — 304 с.
  8. Диаграммы классов UML. URL: https://pro-prof.com/archives/3212
  9. Юнит-тестирование. Пример. Boost Unit Test. URL: https://pro-prof.com/archives/1549
  10. Э. Гамма Приемы объектно-ориентированного проектирования. Паттерны проектирования / Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес. – СПб.: Питер, 2009. – 366 с.

2 Абстракция

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

Но вроде бы лучшие умы сошлись на том, что:

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

В языке программирования Java абстракция осуществляется через использование абстрактных классов и интерфейсов.

Абстракция в реальной жизни

Хороший пример абстракции в реальной жизни — описание должностей в компании или организации. Название должности — это одно, а обязанности каждой конкретной должности — это уже совсем другое.

Представьте, что вы проектируете структуру своей будущей компании. Вы можете разделить обязанности секретаря: «расбросать» их по нескольким другим должностям. Можете разбить должность исполнительного директора на несколько независимых должностей: финансовый директор, технический директор, директор по маркетингу, директор по персоналу. Или, например, объединить должности офис-менеджера и рекрутера в одну.

Вы придумываете названия должностей в своей фирме, а потом «расбрасываете» обязанности по этим должностям. Абстракция – отвлечение от целостности объекта и выделение его главных свойств и составляющих, нужных нам.

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

Классовое наследование

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

Например:

Здесь при помощи ключевого слова из ES6 мы создаём класс  со свойствами и , которые хранятся в . Значения свойств задаются в конструкторе, а доступ к ним осуществляется в методе .

Full Stack Web Developer (Middle+)

Tproger, Москва, От 70 000 до 200 000 ₽

tproger.ru

Вакансии на tproger.ru

Мы создаём экземпляр класса с именем с помощью ключевого слова :

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

Для расширения класса мы можем создать другой класс. Расширим класс с помощью класса . — это с почтой и паролем:

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

Как говорит Дэн Абрамов:

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

Эрик Эллиот описал, как классовое наследование может потенциально привести к провалу проекта, а в худшем случае — к провалу компании:

Когда много производных классов с очень разными функциями наследуются от одного базового класса, любое, казалось бы, безобидное изменение в базовом классе может привести к сбою в работе производных. За счёт усложнения кода и всего процесса создания продукта вы могли бы смягчить побочные эффекты, создав контейнер для инъекций зависимостей. Это обеспечило бы единый интерфейс для создания сервисов, потому что позволило бы абстрагироваться от подробностей создания. Есть ли способ получше?

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

Основными понятиями, используемыми в ООП, являются класс, объект, наследование, инкапсуляция и полиморфизм. В языке Python класс равносилен понятию тип данных.

Что такое класс или тип? Проведем аналогию с реальным миром. Если мы возьмем конкретный стол, то это объект, но не класс. А вот общее представление о столах, их назначении – это класс. Ему принадлежат все реальные объекты столов, какими бы они ни были. Класс столов дает общую характеристику всем столам в мире, он их обобщает.

То же самое с целыми числами в Python. Тип int – это класс целых чисел. Числа 5, 100134, -10 и т. д. – это конкретные объекты этого класса.

В языке программирования Python объекты принято называть также экземплярами. Это связано с тем, что в нем все классы сами являются объектами класса type. Точно также как все модули являются объектами класса module.

>>> type(list), type(int)
(<class 'type'>, <class 'type'>)
>>> import math
>>> type(math)
<class 'module'>

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

Следующее по важности понятие объектно-ориентированного программирования – наследование. Вернемся к столам

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

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

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

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

Отсутствие сокрытия данных в Python делает программирование на нем более легким и понятным, но привносит ряд особенностей, связанных с пространствами имен.

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

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

Вы уже сталкивались с полиморфизмом операции +. Для чисел она обозначает сложение, а для строк – конкатенацию. Внутренняя реализация кода для этой операции у чисел отличается от реализации таковой для строк.

15.1. Основные понятия

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

Объект
характеризуется

  • совокупностью
    всех своих свойств и их текущих значений
    и

  • совокупностью
    допустимых для него действий (их называют
    методами)

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

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

  • инкапсуляция;

  • наследование;

  • полиморфизм.

Инкапсуляцией
называется объединение в одном объекте
как свойств, так и методов (действий над
ними).

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

Н

Наследование
– это такое отношение между объектами,
когда один объект повторяет структуру
и поведение другого, принадлежащего к
более высокому уровню в иерархии.

аследование можно определить
так:

Родительские классы называют просто
родителями (прародителями), а дочерние
потомками.

Классы верхних
уровней иерархии, как правило, не имеют
конкретных экземпляров объектов. Не
существует, например, конкретного живого
организма (объекта), который бы сам по
себе назывался «Млекопитающее» или
«Насекомое». Такие классы называются
абстрактными. Конкретные экземпляры
объектов, или просто объекты, принадлежат
нижележащим уровням иерархии.

Ниже приведен пример иерархии для
насекомых:

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

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

Рассмотрим средства языка Турбо Паскаль
для объектно-ориен-тированного
программирования.

4 Наследование

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

Если нам понадобится что-то создать в реальной жизни, у нас есть два решения:

  1. Создать нужную нам вещь с нуля, потратив кучу времени и сил.
  2. Создать нужную нам вещь на основе уже существующей.

Наиболее оптимальная стратегия выглядит так: берем существующее хорошее решение, немного его дорабатываем, подгоняем под свои нужды и используем.

Если мы проследим историю возникновения человека, то окажется, что с момента зарождения жизни на планете прошли миллиарды лет. А если представить, что человек возник из обезьяны (на основе обезьяны), то прошла всего пара миллионов лет. Создание с нуля — дольше. Гораздо дольше.

В программировании тоже есть возможность создавать один класс на основе другого. Новый класс становится потомком (наследником) уже существующего. Это очень выгодно, когда есть класс, который содержит 80%-90% нужных нам данных и методов. Мы просто объявляем подходящий класс родителем нашего нового класса, и в новом классе автоматически появляются все данные и методы класса-родителя. Правда, удобно?

Наследование

В жизни классы разделены на подклассы. Например, животные делятся на земноводных, млекопитающих, птиц, насекомых и т. д.

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

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

Роль полиморфизма

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

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

Рассмотрим для примера стек, т.е. область памяти, функционирующую по принципу «последним
пришел — первым обслужен». Допустим, что в программе требуются три разных типа
стеков: один — для целых значений, другой — для значений с плавающей точкой, третий — для символьных значений. В данном примере алгоритм, реализующий все эти
стеки, остается неизменным, несмотря на то, что в них сохраняются разнотипные данные. В языке, не являющемся объектно-ориентированным, для этой цели пришлось бы
создать три разных набора стековых подпрограмм с разными именами. Но благодаря
полиморфизму для реализации всех трех типов стеков в C# достаточно создать лишь один общий набор подпрограмм. Зная, как пользоваться одним стеком, вы сумеете
воспользоваться и остальными.

В более общем смысле понятие полиморфизма нередко выражается следующим
образом: «один интерфейс — множество методов». Это означает, что для группы взаимосвязанных действий можно разработать общий интерфейс. Полиморфизм помогает
упростить программу, позволяя использовать один и тот же интерфейс для описания
общего класса действий. Выбрать конкретное действие (т.е. метод) в каждом отдельном
случае — это задача компилятора. Программисту не нужно делать это самому. Ему достаточно запомнить и правильно использовать общий интерфейс.

Философия ООП ¶

Первое, что нужно понять, ООП это лишь один из способов организации кода. С помощью объектов мы разделяем большую логику на на много маленьких, чтобы нам легче было управлять своим же кодом. Это значит, что не нужно во все места совать классы и интерфейсы. Если ООП не упрощает код, а только запутывает, то это неправильное ООП! Каждый раз спрашивайте себя: «А что я упрощу, если сделаю объект?»

Но давайте вернёмся к примеру выше и посмотрим, как можно упростить себе жизнь.

Первое, на что нужно обратить внимание, это то, что мы работаем с пользователем как с массивом:

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

Давайте создадим класс пользователя, который на вход принимает данные пользователя и имеет функцию для возврата имени:

Исправим объявление списка:

Теперь для доступа к имени пользователя можно использовать функцию . Мы «спрятали» (инкапсулировали) структуру исходного массива с данными пользователя за функциями класса . Если исходный массив поменяется, то изменения нужно будет внести только в функции класса.

Дальше решим проблему с постраничной навигацией. Поскольку базовый массив не поддерживает такую навигацию, «спрячем» его в объект, а уже объект «научим» выдавать страницы. Для начала опишем класс коллекции:

Изменим объявление исходных данных:

Теперь можно обращаться к нашим данным так:

Осталось решить проблему с форматом вывода пользователей. Дело в том, что в этом цикле является низкоуровневой логикой, которую надо «прятать». Собственно, также является лишним звеном в этой цепочке. В идеале логику отображения нужно вынести в шаблон и передавать ему список пользователей:

Шаблон представляет из себя псевдо язык разметки, в котором в теории удобно делать вёрстку:

Основная цель таких шаблонов — разделить логику отображения от логики данных. Преимущество, которое нам дают шаблоны заметны сразу: основной код стал «чище» и проще. Ходят легенды, что подобные шаблоны могут делать дизайнеры, верстальщики, папы, мамы, кошки без участия программистов. То есть налицо разделение труда (а если вспомнить историю за 5-й класс, то это уже прогресс в развитии).

Как настроить пользовательский формат

Удаленный рабочий стол Chrome: функции и утилиты

Удаленный рабочий стол Chrome предоставляет несколько полезных функций, которые упрощают работу и позволяют использовать несколько устройств. В то время как использование рабочего стола из другого места может вызвать некоторые материально-технические проблемы, Chrome Remote Desktop позволяет легко избежать наиболее распространенных проблем.

Удаленная поддержка упрощает процесс устранения неполадок. (Изображение предоставлено Google)

Например, если вы используете мобильное устройство, вы можете переключиться в режим клавиатуры или трекпада с помощью кнопки меню в левом нижнем углу. Приложение также включает в себя выделенные пункты меню для Ctrl-Alt-Del и Print Screen.

Мы протестировали Chrome Remote Desktop, получив доступ к iMac 2015 через iPhone SE. К сожалению, в приложении отсутствовали такие важные клавиши, как Command, Control и Option, поэтому многие важные сочетания клавиш были просто недоступны.

С другой стороны, вы должны иметь возможность использовать компьютер удаленно без каких-либо проблем на другом компьютере или ноутбуке. Вы можете перенастроить сопоставления клавиш, если оба устройства имеют физическую клавиатуру. Тем не менее, Chrome Remote Desktop не позволяет передавать файлы между устройствами.

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

Класс

Класс — это такой тип данных, который состоит из единого набора полей и методов.

Имеет внутренние и внешние интерфейсы для управления содержимым. При копировании через присваивание копируется интерфейс, но не данные. Разные виды взаимодействуют между собой посредством:

  • наследования;
  • ассоциации;
  • агрегации.

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

Одной из главных характеристик является область видимости. Понятие по-разному определяется разными ЯП.

В Object Pascal описывается следующим образом:

ClassName = class(SuperClass)

private

{ использование элементов ограничивается только пределами модуля }

{ здесь указываются поля }

strict private

{ спецификатор доступа стал доступным с выходом Delphi 2007, обозначает то же, что и private }

protected

{ элементы могут использоваться внутри ClassName или при наследовании }

public

{ }

published

{ элементы доступны всем, они отображаются в Object Inspector’e }

end;

Здесь SuperClass — предок, от которого происходит наследование.

Для C++ создание выглядит так:

class MyClass: public Parent

{

public:

MyClass(); // конструктор

~MyClass(); // деструктор

protected:

private:

};

В этом примере Parent является предком, если таковой имеется. Спецификаторы private, public, protected обозначают то же самое, что в предыдущем примере на Паскале. Также мы видим конструктор, деструктор, доступные для любой части программы. У C++ все элементы по умолчанию являются private, соответственно, это можно не указывать.

С++ Concept-Based Polymorphism в продуктовом коде: PassManager в LLVM

Сегодня речь пойдет про одну интересную идиому, которую ввел Шон Парент (Adobe) — известный деятель в C++-сообществе. Он часто выступает с докладами и публикует цикл статей Better Code. Одна из его идей, которую используют в Photoshop — это Concept-Based Polymorphism. Это когда мы реализуем полиморфизм не через явное наследование, а с помощью техники, включающей обобщенное программирование, и по итогам получаем некоторые дополнительные преимущества.
Статья устроена следующим образом:

  1. Что вообще такое Concept-Based Polymorphism и зачем он нужен
  2. Немного про LLVM и ее устройство
  3. Пример Concept-Based Polymorphism в LLVM PassManager
  4. Преимущества подхода

Роль инкапсуляции

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

Т.е. инкапсуляция представляет собой способности языка скрывать излишние детали реализации от пользователя объекта.
Например, предположим, что используется класс по имени DatabaseReader, который
имеет два главных метода: Open() и Close().

Фиктивный класс DatabaseReader инкапсулирует внутренние детали нахождения,
загрузки, манипуляций и закрытия файла данных. Программистам нравится инкапсуляция, поскольку этот принцип ООП упрощает кодирование. Нет необходимости беспокоиться о многочисленных строках кода, которые работают «за кулисами», чтобы
реализовать функционирование класса DatabaseReader. Все, что потребуется — это
создать экземпляр и отправлять ему соответствующие сообщения (например, «открыть файл по имени AutoLot.mdf, расположенный на диске С:»).

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

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

Код и данные, составляющие вместе класс, называют членами. Данные, определяемые классом, называют полями, или переменными экземпляра. А код, оперирующий
данными, содержится в функциях-членах, самым типичным представителем которых
является метод. В C# метод служит в качестве аналога подпрограммы. (К числу других
функций-членов относятся свойства, события и конструкторы.) Таким образом, методы класса содержат код, воздействующий на поля, определяемые этим классом.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector