Перейти к содержимому

Что относится к принципам объектно ориентированного программирования

  • автор:

Шпаргалка по принципам ООП

Обложка поста Шпаргалка по принципам ООП

Чтобы стать программистом, нужно знать принципы ООП как Отче наш. Держите структурированную шпаргалку по объектно-ориентированному программированию.

Главное

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

Базовые принципы ООП

  • Абстракция — отделение концепции от ее экземпляра;
  • Полиморфизм — реализация задач одной и той же идеи разными способами;
  • Наследование — способность объекта или класса базироваться на другом объекте или классе. Это главный механизм для повторного использования кода. Наследственное отношение классов четко определяет их иерархию;
  • Инкапсуляция — размещение одного объекта или класса внутри другого для разграничения доступа к ним.

Используйте следующее вместе с наследованием

  • Делегация — перепоручение задачи от внешнего объекта внутреннему;
  • Композиция — включение объектом-контейнером объекта-содержимого и управление его поведением; последний не может существовать вне первого;
  • Агрегация — включение объектом-контейнером ссылки на объект-содержимое; при уничтожении первого последний продолжает существование.

Не повторяйся (Don’t repeat yourself — DRY)

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

Принцип единственной обязанности

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

Принцип открытости/закрытости

Программные сущности должны быть открыты для расширения, но закрыты для изменений.

Принцип подстановки Барбары Лисков

Методы, использующие некий тип, должны иметь возможность использовать его подтипы, не зная об этом.

Принцип разделения интерфейсов

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

Принцип инверсии зависимостей

Система должна конструироваться на основе абстракций “сверху вниз”: не абстракции должны формироваться на основе деталей, а детали должны формироваться на основе абстракций.

Перевод статьи «Object-Orientated Design Principles»

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

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

Вообще устроено все следующим образом: есть само объектно-ориентированное программирование. У него есть принципы. Из принципов объектно-ориентированного программирования следуют разобранные нам шаблоны GRASP (как вариант — SOLID принципы), из которых, в свою очередь, следуют шаблоны GoF. Из них же следует ряд интересных вещей, например, enterprise паттерны.

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

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

Таким образом, система представляется в виде набора объектов предметной области, которые взаимодействуют между собой некоторым образом. Каждый объект обладает тремя cоставляющими: идентичность (identity), состояние (state) и поведение (behaviour).

Состояние объекта — это набор всех его полей и их значений.

Поведение объекта — это набор всех методов класса объекта.

Идентичность объекта — это то, что отличает один объект класса от другого объекта класса. С точки зрения Java, именно по идентичности определяется метод equals.

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

Объектно-ориентированное программирование обладает рядом принципов. Представление об их количестве расходится. Кто-то утверждает, что их три (старая школа программистов), кто-то, что их четыре (новая школа программистов):

  1. Абстрация
  2. Инкапсуляция
  3. Наследование
  4. Полиморфизм

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

Вопреки мнению многих собеседующихся (а иногда и собеседуемых), инкапсуляция это не «когда все поля приватные». Инкапсуляция является фундаментальнейшим принципом проектирования ПО, ее следы наблюдаются на только на уровне микро-, но и на уровне макропроектирования.

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

Таким образом, получается, что если класс A обращается к полям класса B напрямую, это приводит не к тому, что «нарушается информационная безопасность», а к тому, что класс A завязывается на внутренне устройство класса B, и попытка изменить внутреннее устройство класса B приведет к изменению класса А. Более того, класс A не просто так работает с полями класса B, он работает по некоторой бизнес-логике. То есть логика по работе с состоянием класса В лежит в классе А, и когда мы захотим переиспользовать класс В, это не удастся сделать, ведь без кусочка класса А класс В может быть бесполезным, что приведет к тому, что класс В придется отдавать вместе с классом А. Экстраполируя это на всю систему, получается, что переиспользовать можно будет только всю систему целиком.

Инкапсуляция является самым недооцененным принципом, который, к сожалению, мало кем интерпретируется правильно. Она позволяет минимизировать число связей между классами и подсистемами и, соответственно, упростить независимую реализацию и модификацию классов и подсистем.

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

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

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

Полиморфизм

Полиморфизм — это возможность использовать классы – потомки в контексте, который был предназначен для класса – предка.

За самым садистским определением кроется возможность языка программирования для декомпозиции задачи и рефакторинга if’ов и switch’ей.

Что относится к принципам объектно ориентированного программирования

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

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

Одним из самых важных факторов при проектировании компонентов приложения является сокрытие внутренних данных компонента и деталей его реализации от других компонентов приложения и предоставление набора методов для взаимодействия с ним (API). Этот принцип является одним из четырёх фундаментальных принципов ООП и называется инкапсуляцией.

Правильная инкапсуляция важна по многим причинам:

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

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

3. Правильно инкапсулированные компоненты более легки для понимания и процесса отладки, что упрощает поддержку приложения.

В языке Java инкапсуляция реализована с помощью системы классов, которые позволяют собрать информацию об объекте в одном месте; пакетов, которые группируют классы по какому-либо критерию, и модификаторов доступа, которыми можно пометить весь класс или его поле или метод.

Всего модификаторов доступа четыре:

  • public – полный доступ к сущности (полю или методу класса) из любого пакета;
  • protected – доступ к сущности только для классов своего пакета и наследников класса;
  • неявный модификатор по умолчанию (при отсутствии трёх явных) – доступ к сущности только для классов своего пакета;
  • private – доступ только внутри класса, в котором объявлена сущность.

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

Пример корректной инкапсуляции класса:

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

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

Наследование является одним из важнейших принципов объектно-ориентированного программирования, поскольку оно позволяет создавать иерархические структуры объектов. Используя наследование, можно создать общий класс, который будет определять характеристики и поведение, свойственные какому-то набору связанных объектов. В дальнейшем этот класс может быть унаследован другими, более частными классами, каждый из которых будет добавлять уникальные, свойственные только ему характеристики и дополнять или изменять поведение базового класса. В терминах Java такой общий класс называется суперклассом (superclass), или базовым классом (base class), или классом-родителем (parent class), а класс, его наследующий, — подклассом (subclass), или дочерним классом (child class), или классом-потомком (derived class).

Наследование реализует отношение «является» (“is-a”) между суперклассом и подклассом. Пусть, например, классы Employee и Manager представляют собой абстракцию понятий «Сотрудник» и «Менеджер». Каждый менеджер также является сотрудником компании, в которой он работает, следовательно, класс Manager находится в отношении “is-a” с классом Employee. Таким образом, с точки зрения наследования, при выстраивании иерархии классов класс Employee будет являться суперклассом, а класс Manager – дочерним классом. При этом класс, который является наследником какого-либо класса, может быть суперклассом для одного или нескольких других классов. Также в отличие, например, от C++, в Java в строгом смысле отсутствует множественное наследование, то есть любой класс может иметь не более одного класса-родителя. А все классы, суперкласс у которых явно не указан, по умолчанию наследуются от класса Object.

Класс Employee в примере выше является суперклассом не потому, что он главнее класса Manager или содержит больше функциональности. На самом деле верно обратное: функциональность подклассов не ýже, а зачастую существенно шире, чем функциональность их классов-родителей. Приставки «супер-» и «под-» пришли в Java из математики: множество всех менеджеров содержится во множестве всех сотрудников и, таким образом, является подмножеством множества сотрудников.

Для того чтобы унаследовать какой-либо класс в Java, используется ключевое слово extends:

В примере выше класс Employee является базовым классом для класса Manager, а класс Manager – подклассом класса Employee. Класс Employee абстрагирует базовые характеристики для всех сотрудников компании – имя, фамилию, размер оклада и дату приёма на работу, а класс Manager дополняет эти характеристики процентом премии для менеджеров и меняет поведение метода getSalary() базового класса, используя полиморфизм.

Полиморфизм

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

Возьмем для примера абстрактный класс «Автомобиль», который наследуют два конкретных класса – «Спортивный автомобиль» и «Грузовой автомобиль».

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

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

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

Код выше представляет пример полиморфизма. Сначала переменной родительского класса Vehicle присваивается объект дочернего класса SportCar. При вызове метода start() на консоль будет выведено: «Starting my fancy sport car!»

При дальнейшем присвоении этой же переменной объекта дочернего класса Truck и вызове того же метода start() на консоль будет выведено: «Starting my heavy truck!»

Абстракция

Относительно недавно в качестве самостоятельного четвёртого принципа начали выделять абстракцию.

Одно из определений слова «абстракция», которые можно встретить в современных словарях:

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

Все языки программирования предоставляют их пользователю определённые абстракции. Так, языки семейства ассемблер являются в своём роде абстракцией соответствующих микропроцессоров, поскольку позволяют отвлечься от деталей их реализации и общаться с ними через определённый набор более высокоуровневых инструкций. Императивные языки программирования, последовавшие за ассемблером, например Basic, Fortran, C, являются более высоким уровнем абстракции над ассемблерными языками – они дают возможность использовать более привычные человеку синтаксические конструкции за счёт приближения синтаксиса к естественным языкам.

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

Например, класс Student в приложении учёта студентов университета, кроме общих полей, таких как имя, фамилия, дата рождения и т.д., будет содержать поля, отражающие информацию о номере зачётной книжки, статусе студента (действующий, академический отпуск, отчислен), факультете, номере его группы, оценках за семестры и т.д. Но для того же класса Student в приложении учёта студентов в тренинг-центре EPAM такая информация будет неактуальна: класс будет содержать поля, отражающие учебный проект, на который был распределён студент, уровень его английского языка по результатам последнего тестирования, количество посещаемых мероприятий и т.д.

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

Что относится к принципам объектно ориентированного программирования

Всем привет!! создала группу в телеграмм, где Java — студенты смогут не только обсуждать вопросы по изучению Java и делиться полезностями, но и организовывать живые встречи. Кому интересно, вступайте =) https://t.me/JavaCommunityMoscow

chess.rekrut Уровень 25
18 августа 2023
Nikita Dimitrienko Уровень 28
4 августа 2023

Лёгкая в усваивании лекция. Ее бы сразу всем давали. А то я вообще ещё раньше сидел и гуглил все принципы ООП. Читал столько инфы, что просто не пересчитать. А тут в 3-ёх словах всё объяснили)

Alexander Rozenberg Уровень 32
31 июля 2023
Никита Онучин Уровень 25
28 июля 2023
Хорошая лекция! Дополнила понимание ООП
ChupaFx Уровень 32
24 июля 2023
Примеры неудачные, либо неполные.
WORD SOUNDS Уровень 15
18 июля 2023
AnimalBarbershop barbershop = new AnimalBarbershop(); не понял зачем эта строка, подскажите?
Сообщество

JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.

Подписывайтесь
Язык интерфейса
«Программистами не рождаются» © 2024 JavaRush
Скачивайте наши приложения
«Программистами не рождаются» © 2024 JavaRush

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

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

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