Java
- это язык программирования, который поддерживает ООП парадигму.
Про эту парадигму можно говорить очень долго, люди пишут целые книги посвященные этому и именно поэтому, я решил, что лучше дать поверхностное определение ООП
, что называется, "на пальцах". Мы рассмотрим основные принципы, приведем примеры использования и т.д.
Вообще говоря, ООП
- это крайне холиварная тема.
В свое время, да и сейчас тоже, на ней было вскормлено и выращено не одно поколение троллей.
В
Java
мире есть даже люди со своим видением того, что такоеООП
и как с ним работать.Яркий пример - Егор Бугаенко - на момент написания этой статьи его можно было найти по ссылке: Егор Бугаенко.
Рекомендую крайне аккуратно читать его материалы. Там есть много интересных идей, но многие вещи навязываются крайне агрессивно и иногда не совсем логично, на мой взгляд.
Я надеюсь, что вы откроете эту главу при дневном свете - а значит тролли вам не страшны не будут, поэтому давайте начнем.
Главный вопрос на который надо ответить, перед тем, как вы начинаете что-то делать или изучать - это зачем это нужно, зачем вы это делаете.
ООП
не сделает из вас супер специалиста, не увеличит вашу зарплату в десятки раз и прочее.
Однако оно даст нечто большее - оно даст понимание
.
Понимание принципов. С понимания принципов приходит понимание как писать понятный, поддерживаемый и, что самое главное, логичный код.
Давайте ответим на следующий вопрос: Почему вдруг взяли и придумали эту парадигму?
Истинных причин наверное сейчас уже никто не назовет, по крайней мере я их не знаю. Но я думаю по этому поводу вот что:
Одна из основных задач программиста - это борьба со сложностью и с повторяемостью кода. Сложность выражается в проектировании и разработке приложения, модуля и даже блока кода. Борьба с повторяемостью - это попытка переиспользовать уже написанный код, избегая его дублирования.
Основной союзник в борьбе со сложностью - это проектирование вашего приложения и кода.
И ООП
с самого начала будет подталкивать вас к необходимости проектирования - мыслить объектно.
Вы уже не будете работаете с числами и символами - вы составляете из них свои иерархии объектов и классов. Можно сказать, что вы уже мыслите на следующем уровне абстракции - вы оперируете чем-то более сложным, но понятным человеку - объектом. При этом один объект может состоять из других и т.д.
Яркий пример из жизни - это автомобиль. Вы знаете что это такое, вы знаете чего от этого объекта можно ожидать, но то, как он устроен внутри - скорее всего не представляете или же представляете не точно, не до нюансов. Видя машину - вы не думаете, что в ней есть двигатель и болт на двенадцать в левой части правого бензонасоса. Вы видите машину и взаимодействуете с этим объектом как с машиной.
Точно то же самое и в ООП
. Вы оперируете строками и вы в основном не думаете про то, как символы внутри хранятся, за исключением ситуаций, когда это действительно вам нужно, вы работаете со строкой как с объектом.
Попробуйте провести свои аналогии и абстракции?
Если аналогии и абстракции выбраны удачно, то мы увидим четкую картину, которая позволяет нам быстро разобраться в том, как устроена система и что в ней происходит.
Мы будем оперировать такими понятиями как Класс
и Объект
класса, иногда еще говорят instance
класса.
Так вот, Класс
- это описание методов и свойств Объекта
, а Объект
- это уже его сущность.
Если говорить совсем простым языком, то можно сказать: класс - это как техническое описание прибора, купленного вами в электронном дискаунтере. То, каким он должен быть: материал, форма, список составляющих и т.д.
А объект - это уже непосредственно сам прибор, со своим уникальным набором свойств.
Например, у него может быть цвет, материал изготовления, форма, он может состоять также из более мелких узлов(вспомогательных приборов) и т.д
Это все - свойства объекта, они уникальны - для каждого прибора они свои. Свойства объекта - это его состояние
.
Объект
-у также присуще еще и поведение
. Дрелль из магазина вы знаете как себя ведет, а если нет, то ваш сосед, который всегда встает раньше вас - всегда напомнит.
Самое лаконичное описание объекта предложил Буч:
«Объект обладает состоянием, поведением и индивидуальностью».
В ООП
понятию поведение
выделена настолько большая роль, что существует специальный термин для этого - Интерфейс
.
Когда мы садимся за руль автомобиля - вы видите(на момент написания этого текста все было именно так): руль, педали, рычаг коробки переключения передач и т.д. Это по сути и есть интерфейс взаимодействия с машиной.
Всегда существует некоторый ограниченный набор элементов управления, с которыми вы можете взаимодействовать.
Точно то же самое и в программировании! И такой набор элементов называется интерфейс
.
-
Класс
– это способ описания сущности, определяющийсостояние
иповедение
, зависящее от этого состояния, а также правила для взаимодействия с данной сущностью. -
Объект
- это отдельный представительКласса
, имеющий конкретное состояние и поведение, которое полностью определяетсяКлассом
. -
Интерфейс
- это набор методов класса, доступных для использования другими классами.Подробнее про Интерфейс.
Но на этом ООП
не заканчивается. Поэтому давайте продолжим наше знакомство и перейдем к ключевым принципам ООП
.
Прежде всего, какие принципы ООП
мы знаем?
Пока вы не перебили меня, я постараюсь быстро их проговорить.
- Инкапсуляция
- Наследование
- Полиморфизм
- Абстракция
Это фундаментальные свойства. Язык, претендующий называться объектно-ориентированным, должен обладать ими.
О каждом из них поговорим подробнее.
Наследование
— это инструмент, позволяющий описать новый класс на основе уже существующего с частично или полностью заимствованной функциональностью.
Это мощный инструмент переиспользования кода и создания собственных иерархий.
Класс, от которого производится наследование, называется базовым
, родительским
или суперклассом
.
Новый класс — потомком
, наследником
, дочерним
или производным
классом.
Из описания выше можно сделать вывод, что при при наследовании - мы перенимаем и состояние, и поведение класса-родителя.
Необходимо отметить, что производный класс полностью удовлетворяет спецификации родительского, однако может иметь дополнительную функциональность.
Еще раз, наследование - это приобретение и состояния, и поведения класса-родителя.
Эти два и
крайне важны в понимании.
Если вы будете помнить это - вы будете реже ошибаться при использовании наследования.
Самый яркий пример наследования
, который приводится в любых книгах - это иерархия классов фигура, круг, квадрат и т.д.
Круг - это фигура, квадрат - это тоже фигура.
Т.е фигура - это родительский класс, а квадрат и круг - наследники.
Несмотря на кажующуся простоту и неоспоримые плюсы, которые несет за собой подобный подход - у него существует ряд минусов.
Главный минус состоит в том, что удачно применить наследование получается крайне редко, а злоупотребление им настолько серьезно может испортить код и вашу жизнь, что многие считают наследование опасным или даже вредным в использовании.
В
Java
решили ограничить безконтрольное использование тем, что наследоваться можно только от одного родительского класса.Проще говоря - в
Java
отсутствует множественное наследование.
Поэтому использовать наследование надо с умом и осторожностью.
Более подробно об этом в главе, полностю посвященной этой теме:
Слово Инкапсуляция
происходит от лат. in capsula
, capsula
- "коробочка".
Инкапсуляция
- это контроль доступа к полям и методам класса, сокрытие деталей реализации от внешних глаз.
Возвращаясь к примеру с автомобилем - все детали реализации автомобиля скрыты. Вы не доберетесь до мотора просто так, а уж до того, что внутри мотора - тем более. Для вас, как для пользователя, как для водителя, автомобиль предоставляет интерфейс взаимодействия - руль, педали, коробка передач. Вы жемете газ - и едете, при этом что происходит внутри - не важно. Детали реализации машина едет скрыты.
Из этого следует, что инкапсуляция
неразрывно связана с понятием интерфейса
класса.
Грубо говоря, всё то, что не входит в интерфейс, инкапсулируется в классе.
Подробнее про инкапсуляцию:
Представим, что вы получили водительские права. Когда вы получаете права - это говорит о том, что вы умеете водить автомобиль, при этом не важно какой он был марки - вы умеете водить машину, будь это ВАЗ-2109 или Alfa Romeo 159 TI.
Вы садитесь в любой автомобиль и практически сразу знаете что делать. Иначе получалось бы так, что под каждый автомобиль надо было заново учиться и сдавать на права и обучение вождению не имело бы смысла, ведь так?
Ровно о том же самом и Полиморфизм
.
Полиморфизм
– это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Бьерн Страуструп определил полиморфизм как «один интерфейс — множество реализаций»
При этом поведение каждого типа будет зависеть от реализации. Ровно также, как и с автомобилем - несмотря на то, что интерфейс одинаковый и у ВАЗ-2109, и Alfa Romeo 159 TI, однако последний автомобиль будет более резок, быстр и управляем, нежели старина ВАЗ.
Cуществует несколько видов полиморфизма, но в
Java
- параметрический полиморфизм. И поэтому когда мы говорим про полиморфизм в этих заметках - мы имеем в виду именно > параметрический полиморфизм.
Полиморфизм - это мощный инструмент для борьбы с повторяемостью кода.
Подробнее о полиморфизме:
Абстрагирование
– это способ выделить набор значимых характеристик объекта, исключая из рассмотрения незначимые.
Соответственно, Абстракция
– это набор всех таких характеристик.
Основная идея состоит в том, чтобы представить объект минимальным набором полей и методов и при этом с достаточной точностью для решаемой задачи.
Абстракция
- это по сути выстраивание архитектуры вашего кода.
Правильно подобраные абстракции позволят вам сделать вашу программу максимально поддерживаемой и понятной.
Абстрагирование
не является атрибутом исключительно ООП, да и вообще программирования.
Процесс создания уровней абстракции распространяется практически на все области знаний человека.
Так, мы можем делать суждения о материалах, не вдаваясь в подробности их молекулярной структуры. Можем рассуждать о сложных механизмах, например, о компьютере или автомобиле, не вспоминая отдельные детали этих сущностей.
Вы давно и успешно пользуетесь этим инструментом, дело за малым - научиться применять его в программировании.