Лекция
Привет, сегодня поговорим про четыре концепции ооп, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое четыре концепции ооп, определение классы, отношения между классами , настоятельно рекомендую прочитать все из категории Объектно-ориентированное программирование ООП.
В прошлой публикации были рассмотрено «понятие объекта в ООП». В этой заметке будут описаны классы. Это довольно сложная тема, рассмотрение которой подразумевает что Вы знакомы с понятием объекта в объектно-ориентированном программировании.
Рисунок отличие класса и объекта
В любой системе функционирует множество объектов. Некторые из них «похожи» и однотипны. Например, в банковской системе имеется множество объектов-счетов и объектов-клиентов. Однотипные объекты объединяются в классы.
Класс представляет собой шаблон, по которому определяется форма объекта.
В нем указываются данные + код, который будет оперировать этими данными
Следовательно, класс, по существу, представляет собой ряд схематических описаний способа построения объекта. При этом очень важно подчеркнуть, что класс является логической абстракцией. Физическое представление класса появится в оперативной памяти лишь после того, как будет создан объект этого класса.
Классы и структуры — это, по сути, шаблоны, по которым можно создавать объекты. Каждый объект содержит данные и методы, манипулирующие этими данными.
Рисунок составляющие класса
Все объекты одного и того же класса обладают одинаковым интерфейсом и реализуют этот интерфейс одним и тем же способом. Два объекта одного класса в ООП могут отличаться только текущим состоянием, причем всегда теоретически возможно так изменить состояние одного объекта, чтобы он стал равным другому объекту.
Например, продолжая примеры прошлой статьи, у всех объектов-счетов, принадлежащих к классу «Счет», имеется номер и баланс, все они реагируют на сообщение «проверить наличие денег и снять сумму со счета». Важно, что реагируют они на это сообщение одинаково, т.е. реализация метода у всех объектов одного класса одинакова.
Индивидуальные объекты называются экземплярами класса, а класс в ООП — это шаблон по которому строятся объекты.
Таким образом, наша банковская система состоит из экземпляров трех классов: класса счетов, класса банкоматов и класса клиентов. Названия классов в ООП пишутся с большой буквы, а названия объектов — с маленькой.
Данные-члены — это те члены, которые содержат данные класса – поля, константы, события.
Поля (field)
Это любые переменные, ассоциированные с классом.
Константы
Константы могут быть ассоциированы с классом тем же способом, что и переменные. Константа объявляется с помощью ключевого слова const. Если она объявлена как public, то в этом случае становится доступной извне класса.
События
Это члены класса, позволяющие объекту уведомлять вызывающий код о том, что случилось нечто достойное упоминания, например, изменение свойства класса либо некоторое взаимодействие с пользователем. Клиент может иметь код, известный как обработчик событий, реагирующий на них.
Функции-члены — это члены, которые обеспечивают функциональность для манипулирования данными класса.
Они включают методы, свойства, конструкторы, финализаторы, операции и индексаторы:
Методы (method)
Это функции, ассоциированные с определенным классом. Как и данные-члены, по умолчанию они являются членами экземпляра. Они могут быть объявлены статическими с помощью модификатора static.
Свойства (property)
Это наборы функций, которые могут быть доступны клиенту таким же способом, как общедоступные поля класса. В C# предусмотрен специальный синтаксис для реализации чтения и записи свойств для классов, поэтому писать собственные методы с именами, начинающимися на Set и Get, не понадобится. Поскольку не существует какого-то отдельного синтаксиса для свойств, который отличал бы их от нормальных функций, создается иллюзия объектов как реальных сущностей, предоставляемых клиентскому коду.
Конструкторы (constructor)
Это специальные функции, вызываемые автоматически при инициализации объекта. Их имена совпадают с именами классов, которым они принадлежат, и они не имеют типа возврата. Конструкторы полезны для инициализации полей класса.
Финализаторы (finalizer)
Вызываются, когда среда CLR определяет, что объект больше не нужен. Они имеют то же имя, что и класс, но с предшествующим символом тильды. Предсказать точно, когда будет вызван финализатор, невозможно.
Операции (operator)
Это простейшие действия вроде + или -. Когда вы складываете два целых числа, то, строго говоря, применяете операцию + к целым. Однако C# позволяет указать, как существующие операции будут работать с пользовательскими классами (так называемая перегрузка операции).
Индексаторы (indexer)
Позволяют индексировать объекты таким же способом, как массив или коллекцию
Рисунок Основные понятия классов
Рисунок Обозначение класса на диаграмме классов в UML.
Представленная ниже графическая схема классов соответствует обозначениям, принятым в Унифицированном языке моделирования UML.
Рисунок Классы в учебной банковской системе
В реальности же, счета могут быть различными. Об этом говорит сайт https://intellect.icu . Срочный вклад отличается от расчетного и от вклада до востребования. У них имеются разные характеристики, и они по-разному реализуют одни и теже операции. Поэтому для их описания нужны разные классы.
Рисунок Разделение счетов на разные классы
Чем отличается понятие класса в ООП от таких понятий как «интерфейс» или «тип»?
Интерфейс — это внешняя часть класса. Интерфейс определяет, как объекты данного класса могут взаимодействовать с другими объектами этого или других классов. Однако, если у двух объектов совпадают интерфейсы это еще не значит что они принадлежат к одному и тому же классу. Кроме совпадения интерфейсов необходимо, чтобы и их реализация и поведение были одинаковыми.
Тип — это область определения некой величины, т.е. множество ее возможных значений и набор применимых операций. Тип может задаваться классом.
Важнейшим свойством классов в ООП и их принципиальным отличием от абстрактных типов данных (встроенных в язык программирования) являетсянаследование. Наследование — это отношение между классами, при котором один класс разделяет структуру или поведение одного или нескольких других классов.
Механизм наследования классов в ООП позволяет выделить общие части разных классов. В приведенном выше примере, были выделены разные типы счетов в банковской системе. Однако они имеют много общего. Выделив общую часть, можно создать класс «Счет». Классы «Расчетный счет» и «Депозит» сохраняют все свойства (как методы, так и атрибуты) класса «Счет», дополняя и уточняя его поведение. Говорят что класс «Депозит» наследует класс «Счет». Графически это изображается в виде иерархии.
Рисунок Схема наследования классов-счетов
Наследование классов в ООП может быть многоуровневым. Пример такой многоуровневой структуры классов-счетов представлен ниже.
Рисунок Схема многоуровневого наследования классов
Иерархию классов в ООП можно построить по-разному. Фактически иерархия классов является классификатором объектов. В данном случае при построении системы классов разработчик пытается принять во внимание следующие соображения «Столь ли существенна разница между рублевыми и валютными вкладами, что их следует разделить на различные классы?», «Разные виды Депозитов — это разные характеристики одного и того же класса или же разные классы?» и т.п.
Как видно из рисунка, представленного выше, разница между рублевым и валютным счетом настолько существенна, что они выделены в разные классы. Разные виды Депозитов также представлены разными классами. Если бы решили, что денежная единица, в которой выражается сумма на счете, — лишь дополнительны атрибут счета, и разные типы депозитов различаются дополнительной характеристикой класса «Депозит», то иерархия классов преобразовалась бы к виду, изображенному на рисунке:
Рисунок Упрощенная иерархия валютных и рублевых счетов
Важно отметить, что в ООП существует особый тип классов — абстрактные классы. Абстрактные классы — это классы для которых не существует экземпляров, они лишь описывают общие характеристики классов-потомков. В нашем случае абстрактным классом можно считать класс «Счет», т.к. фактически экземпляров данного класса не существует. Зато он используется для реализации общего интерфейса для классов-потомков.
Конкретные классы — это классы экземпляры которых могут существовать (или существуют) в системе в отличии от абстрактных классов.
Механизм абстрактных классов в ООП является чрезвычайно мощным понятием, которое широко используется. Назначением абстрактных классов в ООП является определение общих, наиболее характерных методов и атрибутов наследуемых из них классов. Чаще всего абстрактные классы используются для задания общего интерфейса иерархии конкретных классов, хотя и атрибуты, и реализация каких-либо методов могут присутствовать в абстрактных классах.
Рассмотренные до сих пор примеры показывали как класс в ООП может унаследовать методы и атрибуты одного базового класса. Такое наследование носит название одинарного или простого наследования. Наряду с ним существует и множественное наследование, при котором у одного класса имеется несколько базовых.
Множественное наследование в ООП позволяет объединять характеристики различных классов в одном. Мы рассмотрели иерархию классов для представления счетов в банковской системе, которая отображает функциональные характеристики счетов — возможности пожить или снять деньги со счета. С другой стороны, при реализации этой банковской системы многие объекты, в том числе и счета, должны храниться в базе данных. Система классов, обеспечивающая хранение объектов в базе данных, может состоять из базового класса «Постоянный объект», у которого есть методы сохранить и извлечь для реализации записи и чтения из базы данных, а атрибуты «имя таблицы» и «номер строки» для описания местоположения объекта. Для того чтобы какой-либо конкретный счет стало возможным хранить в базе данных, он должен быт выведен из класса «Постоянный объект».
Рисунок Множественное наследование
Класс «Валютный депозит» наследует атрибуты и методы обоих своих родителей.
Рисунок основные концепции ООП
Абстракция. Важно помнить, что описывая поведение любого объекта, нужно выбрать подходящий для решения конкретной задачи уровень абстракции. Объекты реального мира могут быть достаточно сложны, чтобы описать все их характеристики, более того, решения конкретных задач потребует лишь наличие некоторых из них. Таким образом, мы должны абстрагироваться от некоторых конкретных деталей объекта. Но также важно, чтобы абстракция не была слишком обобщенной и позволила правильно моделировать поведение объекта.
Инкапсуляция - это механизм, который объединяет атрибуты и методы (которые составляют объект) и предохраняет их от внешнего вмешательства. Инкапсуляция - защитная оболочка, позволяющая обращаться к атрибутам и методов класса только внутри этого класса или с помощью специально спроектированного интерфейса.
Атрибуты или методы класса могут быть открытыми (public) или закрытыми (private). Закрытые атрибуты и методы могут быть доступны только внутри класса, в котором они находятся, они не доступны той части программного кода, которая находится вне этого класса. Открытые атрибуты и методы доступны, в том числе, и кода программы вне класса. Таким образом, открытые методы используются для предоставления контролируемого интерфейса к закрытым элементов класса.
Например, представим, что у робота на голове находятся светодиоды, которые меняют цвет по голосовой команде «Измени цвет». Мы не можем ни как иначе повлиять на изменение цвета диодов, потому что этого не позволят настройки приватности. Мы можем повлиять на изменение цвета, только с помощью конкретной голосовой команды, которая в данном случае является интерфейсом к светодиодам.
Наследование помогает избежать дублирования кода в случае, если нам нужно создать объект на основе уже существующего. В этом случае говорится, что новый объект (дочерний) унаследовал свойства уже существующего (родительского). Если атрибуты или поведение существующего объекта нужно частично изменить, то их можно просто переопределить.
Например, на основе уже существующего объекта Robot мы можем создать новый объект CoffeRobot, который будет варить кофе. Новый робот будет все атрибуты и методы что и предыдущий, плюс содержать дополнительный метод «Варить кофе».
Полиморфизм
Если мы имеем объекты, которые принадлежат одной и той же ветви иерархии (были унаследованы), то для них можно использовать единый интерфейс, который будет для каждого объекта производить однотипное действие, но результат для каждого объекта будет различным (зависящим от этого конкретного объекта).
Например, если мы при помощи наследования создадим серию роботов разных типов (робот, который варит кофе; робот, который моет пол; робот, который поливает цветы), а потом каждому роботу дадим команду «работай», то каждый робот в ответ на ту же самую команду будет делать различные действия, в соответствии с его типом. То есть, единым интерфейсом здесь является объект Robot с методом «работать», а то, как именно он будет работать, зависит от его реализации.
Полиморфизм - это возможность взаимодействия с объектом, не зная, к какому конкретному классу он относится. Например, посылая сообщение любому счету мы используем полиморфизм всех счетов.
В данном случае полиморфизм является ограниченным. Если сообщение «снять» будет послано, например, клиенту, он не сможет его обработать, т.е. нам не важно какой конкретно счет обрабатывает сообщение, но тем не менее это должен быть счет, объект одного из классов, выделенных из базового класса «Счет».
В большинстве случаев используется именно ограниченный полиморфизм. Тем не менее, иногда любой объект системы может обработать некоторое сообщение. Например, в языке Java у всех объектов имеется метод toString, приводящий значение объекта к строковому виду, соответственно любому объекту независимо от его класса можно послать сообщение toString.
При использовании полиморфизма в ООП используется знание интерфейса объекта, однако поведение конкретного объекта в ответ на полученное сообщение может быть различно в зависимости от конкретного класса этого объекта. Соответственно посылающий сообщение объект точно не знает, что произойдет при вызове метода.
Наследования (Генерализация) - объекты дочернего класса наследуют все свойства родительского класса.
Ассоциация - объекты классов вступают во взаимодействие между собой.
Агрегация - объекты одного класса входят в объекты другого.
Композиция - объекты одного класса входят в объекты другого и зависят друг от друга по времени жизни.
Класс-метаклассы - отношение, при котором экземплярами одного класса есть другие классы.
Рисунок Нотация UML для отображения взаимосвязи между классами на диаграммах
Надеюсь, эта статья про четыре концепции ооп, была вам полезна, счастья и удачи в ваших начинаниях! Надеюсь, что теперь ты понял что такое четыре концепции ооп, определение классы, отношения между классами и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Объектно-ориентированное программирование ООП
Комментарии
Оставить комментарий
Объектно-ориентированное программирование ООП
Термины: Объектно-ориентированное программирование ООП