Skip to content

Latest commit

 

History

History
202 lines (122 loc) · 19.1 KB

intro.md

File metadata and controls

202 lines (122 loc) · 19.1 KB

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

Введение

Java - это язык программирования, который поддерживает ООП парадигму.

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

Осторожно

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

В Java мире есть даже люди со своим видением того, что такое ООП и как с ним работать.

Яркий пример - Егор Бугаенко - на момент написания этой статьи его можно было найти по ссылке: Егор Бугаенко.

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

Я надеюсь, что вы откроете эту главу при дневном свете - а значит тролли вам не страшны не будут, поэтому давайте начнем.

Зачем это нужно

Главный вопрос на который надо ответить, перед тем, как вы начинаете что-то делать или изучать - это зачем это нужно, зачем вы это делаете.

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

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

Давайте ответим на следующий вопрос: Почему вдруг взяли и придумали эту парадигму?

Истинных причин наверное сейчас уже никто не назовет, по крайней мере я их не знаю. Но я думаю по этому поводу вот что:

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

Основной союзник в борьбе со сложностью - это проектирование вашего приложения и кода.

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

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

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

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

Попробуйте провести свои аналогии и абстракции?

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

Базовые понятия

Мы будем оперировать такими понятиями как Класс и Объект класса, иногда еще говорят instance класса. Так вот, Класс - это описание методов и свойств Объекта, а Объект - это уже его сущность.

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

А объект - это уже непосредственно сам прибор, со своим уникальным набором свойств.

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

Это все - свойства объекта, они уникальны - для каждого прибора они свои. Свойства объекта - это его состояние.

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

Самое лаконичное описание объекта предложил Буч:

«Объект обладает состоянием, поведением и индивидуальностью».

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

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

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

Закрепим

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

  • Объект - это отдельный представитель Класса, имеющий конкретное состояние и поведение, которое полностью определяется Классом.

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

    Подробнее про Интерфейс.

Но на этом ООП не заканчивается. Поэтому давайте продолжим наше знакомство и перейдем к ключевым принципам ООП.

Ключевые черты ООП

Прежде всего, какие принципы ООП мы знаем?

Пока вы не перебили меня, я постараюсь быстро их проговорить.

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

Это фундаментальные свойства. Язык, претендующий называться объектно-ориентированным, должен обладать ими.

О каждом из них поговорим подробнее.

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

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

Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом.

Из описания выше можно сделать вывод, что при при наследовании - мы перенимаем и состояние, и поведение класса-родителя.

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

Еще раз, наследование - это приобретение и состояния, и поведения класса-родителя. Эти два и крайне важны в понимании. Если вы будете помнить это - вы будете реже ошибаться при использовании наследования.

Самый яркий пример наследования, который приводится в любых книгах - это иерархия классов фигура, круг, квадрат и т.д. Круг - это фигура, квадрат - это тоже фигура. Т.е фигура - это родительский класс, а квадрат и круг - наследники.

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

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

В Java решили ограничить безконтрольное использование тем, что наследоваться можно только от одного родительского класса.

Проще говоря - в Java отсутствует множественное наследование.

Поэтому использовать наследование надо с умом и осторожностью.

Более подробно об этом в главе, полностю посвященной этой теме:

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

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

Слово Инкапсуляция происходит от лат. in capsula, capsula - "коробочка".

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

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

Из этого следует, что инкапсуляция неразрывно связана с понятием интерфейса класса. Грубо говоря, всё то, что не входит в интерфейс, инкапсулируется в классе.

Подробнее про инкапсуляцию:

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

Полиморфизм

Представим, что вы получили водительские права. Когда вы получаете права - это говорит о том, что вы умеете водить автомобиль, при этом не важно какой он был марки - вы умеете водить машину, будь это ВАЗ-2109 или Alfa Romeo 159 TI.

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

Ровно о том же самом и Полиморфизм.

Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.

Бьерн Страуструп определил полиморфизм как «один интерфейс — множество реализаций»

При этом поведение каждого типа будет зависеть от реализации. Ровно также, как и с автомобилем - несмотря на то, что интерфейс одинаковый и у ВАЗ-2109, и Alfa Romeo 159 TI, однако последний автомобиль будет более резок, быстр и управляем, нежели старина ВАЗ.

Cуществует несколько видов полиморфизма, но в Java - параметрический полиморфизм. И поэтому когда мы говорим про полиморфизм в этих заметках - мы имеем в виду именно > параметрический полиморфизм.

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

Подробнее о полиморфизме:

Полиморфизм

Абстракция

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

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

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

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

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

Вы давно и успешно пользуетесь этим инструментом, дело за малым - научиться применять его в программировании.