5.A Профессор Фортран об ОБЪЕКТЕ в программировании
![](https://img.golos.io/proxy/https://i.imgur.com/f5CoVGu.jpg)
![](https://img.golos.io/proxy/https://i.imgur.com/i5jcUvW.jpg)
Фортран: Дорогие друзья, сегодня я хотел бы поговорить об объектно-ориентированном программировании (ООП), что такое объект и зачем все это было придумано. Все дело в том, что потребности в новом и более мощном программном обеспечении (ПО) постоянно растут, а его быстрая, правильная и экономичная разработка выходит на первый план.
![](https://img.golos.io/proxy/https://i.imgur.com/gt3PHwJ.jpg)
Воробей: Так что же такое объекты, и какие объекты существуют?
![](https://img.golos.io/proxy/https://i.imgur.com/CQfaoou.jpg)
Фортран: Если коротко, то объекты, или точнее, классы объектов являются по существу многоразовыми программными компонентами. Есть объекты даты, объекты времени, объекты аудио, объекты видео, объекты автомобили, объекты люди и т.д. Почти любое существительное может быть представлено как программный объект со своими атрибутами (например, имя, цвет и размер) и поведением (например, умение делать вычисления, двигаться и общаться). Например, ты, Воробей – это объект со своими размерами и цветом и умением летать. За счет появления объектно-ориентированного проектирования разработка программного обеспечения стала модульной, что позволило программистам быть более продуктивными, чем при написании программ на процедурных языках программирования, которые еще совсем недавно были наиболее популярны. Объектно-ориентированные программы часто легче для понимания, внесения исправлений и изменений.
![](https://img.golos.io/proxy/https://i.imgur.com/w7bm4tk.jpg)
Воробей: Профессор, про себя я понял, а можно еще пример?
![](https://img.golos.io/proxy/https://i.imgur.com/iJ3rDdf.jpg)
Фортран: Легко, давай даже попробуем объяснить всю терминологию ООП на примере простой аналогии. Предположим, кто-то хочет поехать на автомобиле, заставив его ехать очень быстро, нажимая на педаль газа. Что перед этим должно произойти?
![](https://img.golos.io/proxy/https://i.imgur.com/HVjStQf.jpg)
Воробей: Ну, если заходить совсем издалека, то автомобиль нужно купить, прежде на нем кататься.
![](https://img.golos.io/proxy/https://i.imgur.com/kWVSeTb.jpg)
Фортран: Ты почти уловил мою мысль, но не до конца. Для начала кто-то должен спроектировать автомобиль. Любой автомобиль начинается с инженерных чертежей. В этих чертежах описана и педаль газа. Педаль газа скрывает от водителя сложный механизм, который заставляет автомобиль ехать быстрее, точно также как и педаль тормоза скрывает механизм торможения, а руль скрывает механизм поворота автомобиля. Такой подход позволяет людям без специальных знаний о двигателе, торможении и рулевом управлении легко и непринужденно управлять автомобилем.
Однако вы не можете сесть за руль инженерных чертежей. До того как вы сможете поехать на автомобиле, он должен быть собран в соответствии с чертежами. Т.е. должен быть собран объект реального мира. Собранный автомобиль будет иметь педаль газа, но одного этого недостаточно — автомобиль не будет ускоряться сам по себе, т.к. на педаль кто-то должен нажимать. И тут мы подходим к понятию метода.
![](https://img.golos.io/proxy/https://i.imgur.com/f9cI33u.jpg)
Воробей: А я вот слышал, что методы располагаются в каких-то классах, только не понял, это как наш компьютерный класс?
![](https://img.golos.io/proxy/https://i.imgur.com/qWSx1WN.jpg)
Фортран: Не совсем так, а точнее совсем не так. Выполнение любой задачи в программе требует наличия метода. В методе размещены программные инструкции, которые на деле выполняют задачи, поставленные перед этим методом. Метод скрывает эти инструкции от пользователя, точно также как и педаль газа скрывает от водителя механизм, заставляющий автомобиль ехать быстрее.
В Java, мы создаем программный модуль, который называем классом, чтобы вместить методы, выполняющие задачи всего класса. Например, класс, который представляет счет в банке, вероятно, будет содержать один метод для внесения денег на счет, второй для списания денег со счета, и третий для запроса текущего баланса. Если вернуться к примеру с автомобилем, то класс эквивалентен инженерному чертежу, описывающему что проектируемый объект должен уметь делать через его методы и как он это должен делать через программные инструкции, записанные в этих методах.
![](https://img.golos.io/proxy/https://i.imgur.com/lxmtIaQ.jpg)
Воробей: О, я понял. Класс – это чертеж, т.е. идея некого объекта, который нужно еще по этому чертежу создать, а метод – это то, что будущий объект будет уметь делать. Верно?
![](https://img.golos.io/proxy/https://i.imgur.com/dNtWm2O.jpg)
Фортран: Воробей, да ты схватываешь на лету ;) Раз ты это понял, то перейдем к созданию объекта из класса.
Точно также как кто-то должен собрать автомобиль по инженерным чертежам перед тем, как вы сможете его оседлать, вы должны построить объект из класса до того как программа сможет выполнить задачи, заданные в методах класса. Процесс создания объекта из класса называется созданием экземпляра класса, а каждый такой экземпляр иногда еще называется инстансом (instance). Таким образом, объект и экземпляр класса - понятия равнозначные.
![](https://img.golos.io/proxy/https://i.imgur.com/8AMZ0WC.jpg)
Воробей: Правильно ли я понимаю, что ООП нужно для того, чтобы в программировании можно было оперировать понятиями близкими к реальной жизни?
![](https://img.golos.io/proxy/https://i.imgur.com/asxNGqq.jpg)
Фортран: Да, т.к. это помогает программистам мыслить привычными категориями при проектировании сложных программных систем. Но об этом чуть позже. Давай разберем одно очень важное преимущество ООП – повторное использование кода.
Точно также как по одному и тому же инженерному чертежу может быть создан не один автомобиль, вы также можете из одного и того же класса создать столько объектов сколько вам будет нужно.
Повторное использование существующих классов для создания других классов и целых программ экономит время и силы программиста. Повторное использование позволяет строить более надежные и эффективные приложения, потому что существующие классы и компоненты часто уже были подвергнуты обширному и всестороннему тестированию, отладке и оптимизации. Точно также как идея взаимозаменяемых частей была решающей в эпоху индустриальной революции, повторно используемые классы стали решающей идеей для софтверной революции, которая произошла с появлением ООП.
Позволь, дать тебе одну рекомендацию, которой многие программисты пренебрегают – при создании собственных программ используй принцип компоновки из готовых программных блоков. Не изобретай велосипед — используй существующие высококачественные программные блоки везде, где это возможно. Идея повторного использования – это главная заслуга ООП.
![](https://img.golos.io/proxy/https://i.imgur.com/vHAcA6m.jpg)
Воробей: Профессор, вот вы говорили, что наличие автомобиля, т.е. объекта, и педали газа, т.е. метода, еще не достаточно, чтобы автомобиль поехал. А что же тогда еще нужно?
![](https://img.golos.io/proxy/https://i.imgur.com/wsMJU96.jpg)
Фортран: Молодец, Воробей, ты, оказывается, меня очень внимательно слушаешь! Конечно, ты прав. Педаль газа еще нужно нажать, а метод – вызвать.
Когда кто-то ведет автомобиль, давление на педаль газа можно расценивать как отправку сообщения автомобилю с требованием выполнения задачи, а именно, требования, что автомобиль должен ехать быстрее.
Подобным образом мы отправляем сообщение объекту. Каждое сообщение реализовано как вызов метода, которое говорит методу объекта выполнить заложенную в него задачу. Например, программа может вызвать метод внесения денег на банковский счет в объекте банковского счета для пополнения баланса.
![](https://img.golos.io/proxy/https://i.imgur.com/dNG083O.jpg)
Воробей: А как насчет цвета автомобиля и его длины. Каким образом эти данные хранятся в объекте?
![](https://img.golos.io/proxy/https://i.imgur.com/jYgGZmP.jpg)
Фортран: Верное замечание. Автомобиль, кроме своей способности выполнять задачи, также имеет атрибуты, такие как цвет, количеств дверей, количество бензина в бензобаке, текущая скорость, километраж (т.е. показания одометра). Как и способности (методы), так и атрибуты автомобиля являются частью инженерного решения, которое, например, предполагало размещение в автомобиле одометра и датчика топлива. Эти атрибуты неотделимы от автомобиля и являются его частью. Каждый автомобиль знает о значениях только своих атрибутов, например, только своего уровня топлива, но не об уровне топлива в других автомобилях.
Аналогичным образом атрибутами обладает и объект. Эти атрибуты прописаны в классе объекта. Например, объект банковского счета имеет атрибут текущего баланса, который несет информацию о количестве денег на этом счете. Каждый объект банковского счета знает о текущем балансе счета, который он представляет, но не о балансах других счетов в банке. Значения атрибутов хранятся в переменных экземпляра класса.
![](https://img.golos.io/proxy/https://i.imgur.com/BAhxcvj.jpg)
Воробей: Профессор, а объекты могут друг в друга заглядывать, чтобы подсмотреть, как они устроены?
![](https://img.golos.io/proxy/https://i.imgur.com/3ldgouy.jpg)
Фортран: В обычной ситуации это недопустимо. Классы (и их объекты) инкапсулируют, т.е. упаковывают, свои атрибуты и методы. При этом атрибуты и методы класса (объекта) тесно связаны между собой. Объекты могут взаимодействовать друг с другом, но при этом в нормальных условиях объекты не позволяют другим объектам знать, как они реализованы — детали реализации скрыты внутри самих объектов. Сокрытие подобной информации, и мы в этом убедимся позднее, является очень важной идеей в разработке программного обеспечения.
![](https://img.golos.io/proxy/https://i.imgur.com/XVqe0Iz.jpg)
Воробей: А я вот подумал. Я вот птица, но и голубь тоже птица. У нас есть крылья и клюв. Так что же получается, если программист захочет описать все объекты реального мира, ему придется и для воробья описывать наличие клюва и крыльев, и для голубя, и для всех птиц в мире писать одно и тоже?
![](https://img.golos.io/proxy/https://i.imgur.com/vNACtKh.jpg)
Фортран: Очень правильный вопрос. Нет, не придется, для этого в ООП придумано такое понятие как наследование.
Новые классы объектов могут быть созданы не только с чистого листа, но и через наследование от старых классов. При этом новый класс, называемый дочерним или подклассом (subclass), начинает свое существование с характеристиками родительского или суперкласса (superclass). При этом в нем можно настроить существующие (родительские) и даже добавить свои собственные уникальные характеристики. В нашей аналогии с автомобилем объект класса «кабриолет» определенно будет являться дочерним по отношению к более общему родительскому классу «автомобиль» с добавлением дополнительного функционала по поднятию и опусканию крыши.
Но и это еще не все. Java также поддерживает интерфейсы – коллекции связанных методов, которые должны сказать объекту, что делать, но не как это делать (правда, когда мы дойдем до особенностей, появившихся с Java 8, мы увидим исключение из этого правила).
В аналогии с автомобилем, можно описать интерфейс базовых возможностей автомобиля, состоящий из поворота руля, нажатия педалей газа и тормоза, которые описывают, что можно делать, но не как. И знания этого интерфейса достаточно, чтобы водить разные виды автомобилей, вне зависимости от того, как на заводе был реализован этот функционал.
Класс может реализовывать несколько интерфейсов или не реализовывать их вовсе. Каждый из интерфейсов может иметь от 0 и более методов. В аналогии с автомобилем, например, у нас есть один интерфейс для базовых функций вождения (газ-тормоз-поворот), другой интерфейс для управления радио, обогревом и кондиционером.
Точно также как разные производители автомобилей реализуют один и тот же функционал по-разному, разные классы могут реализовывать один и тот же интерфейс по-разному. Например, можно придумать backup-интерфейс с методами сохранения и восстановления. В зависимости от того, что именно описывает класс, реализация backup-интерфейса может отличаться. Например, backup текста может отличаться от backup-а аудио- и видеоконтента. Также процедура backup-а может отличаться от типа носителя, на который мы делаем backup, например, на диск или в сеть.
![](https://img.golos.io/proxy/https://i.imgur.com/NzTaJDy.jpg)
Воробей: Профессор, вы что-то говорили про проектирование сложных программных систем, вы не могли бы раскрыть эту тему чуть подробнее?
![](https://img.golos.io/proxy/https://i.imgur.com/iH8npUb.jpg)
Фортран: Конечно, я как раз хотел вернуться к этому вопросу.
Смотри, скоро ты начнешь писать программы на Java. Как ты будешь писать код, т.е. программные инструкции, своих программ? Вероятно, как и многие программисты, ты просто включишь компьютер и начнешь печатать.
![](https://img.golos.io/proxy/https://i.imgur.com/g8CMl9F.jpg)
Воробей: А то, а что можно как-то иначе?
![](https://img.golos.io/proxy/https://i.imgur.com/iTzPwEp.jpg)
Фортран: Можно и нужно, т.к. твой подход к программированию годится лишь для относительно маленьких программ, с которых мы начнем наш путь обучения.
Но что если бы тебя попросили создать программу для управления тысячами банкоматов? Или, предположим, тебя попросили поработать в команде из 1000 разработчиков, создающих следующее поколение систем управления воздушным транспортом? Для таких крупных и сложных проектов не достаточно просто сесть и начать писать программу.
Для выработки лучшего решения, нужно детально изучить процесс для определения требований к проекту, т.е. определить, что система должна делать, и продумать, как удовлетворить эти требования, т.е. определить, как система должна это делать.
В идеале, ты должен будешь все это сделать вместе с другими программистами до того, как вы приступите к написанию первых строчек кода. При этом, если вы проводите такой анализ и проектирование с объектно-ориентированной точки зрения, т.е. в этом процессе оперируете понятиями объекта, то такой процесс называется объектно-ориентированным анализом и проектированием (ООАП).
Такие языки как Java – объектно-ориентированы, и поэтому позволяют не просто сесть и писать код, а реализовывать результаты объектно-ориентированного анализа и проектирования в рабочую программную систему.
И напоследок хочу сказать, что хотя и существует множество способов представления результатов ООАП, только язык UML (универсальный язык моделирования) стал в этом деле стандартом. UML – это наиболее распространенная графическая форма представления результатов моделирования объектно-ориентированных систем и в нашем процессе обучения мы еще с ним столкнемся.
На этом я хотел бы закончить вводный урок в ООП. На следующем уроке мы поговорим подробнее о том, что же такое язык Java.