Компьютеры и современные гаджеты

Объектно-ориентированное программирование (ООП) является в настоящее время наиболее популярной технологией про­граммирования. Объектно-ориентированное программирова­ние является развитием технологии структурного програм­мирования, однако имеет свои характерные черты.

Наиболее распространенными системами объектно-ориен­тированного визуального программирования являются Mic­rosoft Visual Basic и Borland Delphi.

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

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

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

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

Основной единицей в объектно-ориентированном про­граммировании является объект, который заключает в себе, – инкапсулирует как описывающие его данные (свойства), так средства обработки этих данных (методы).

Инкапсуляцией называется объединение в объекте его свойств и возможных над ним операций (методов).

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

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

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

Еще один принцип ООП – принцип полиморфизма.

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

Полиморфизм обеспечивается тем, что в классе-потомке изменяют реализацию метода класса-предка с обязательным сохранением сигнатуры метода. Это обеспечивает сохранение неизменным интерфейса класса-предка и позволяет осуществить связывание имени метода в коде с разными классами - из объекта какого класса осуществляется вызов, из того класса и берётся метод с данным именем. Такой механизм называется динамическим (или поздним) связыванием - в отличие от статического (раннего) связывания, осуществляемого на этапе компиляции

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

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

Таким образом, в объект­но-ориентированном программи­ровании центральное место занимают объекты, которые объ­единяют в одно целое (инкапсулируют) свойства объекта и возможные над ним операции (методы).

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

Например, файловая система компьютера может содер­жать сотни и тысячи файлов. Все файлы обладают одним я тем же набором свойств (имя, положение в файловой системе и др.) и операций (переименование, перемещение или ко­пирование и др.) и образуют класс объектов Файлы.

Каждый отдельный файл является экземпляром этого класса и имеет конкретные значения свойств (имя, местопо­ложение и др.).

Часто встречается ситуация, когда над объектами различных классов можно совершать одинако­вые операции. Для большинства классов объектов в среде Windows (папки, документы, символы и др.) также характерен набор одних и тех же операций (переименование, перемещение, копирование, удаление и т.д.). Такое единообразие очень удобно для пользователя.

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

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

Объекты, обладающие одинаковыми наборами свойств и методов, образуют класс объектов. Так, в приложении Word существует класс объектов документ (Documents), который обладает такими свойствами как имя (Name), местоположе­ ние (FileNaine) и др. Объекты этого класса обладают также определенным набором методов, например: открытие доку­ мента (Open), печать документа (Printout), сохранение документа (Save) и т.д.

Объекты в приложениях образуют некоторую иерархию. На вершине иерархии объектов находится приложение (Ap­plication). Так, иерархия объектов приложения Word включает в себя следующие объекты: приложение (Applica­tion), документ (Documents), фрагмент документа (Se­lection), символ (Character) и др.

Иерархия объектов приложения Excel включает в себя следующие объекты: приложение (Application), книга (Workbook), лист (Worksheet), диапазон ячеек (Range), ячей­ ка (Cell) и др.

Полная ссылка на объект состоит из ряда имен вложен­ных последовательно друг в друга объектов. Разделителями имен объектов в этом ряду являются точки, ряд начинается с объекта наиболее высокого уровня Application и заканчи­вается именем интересующего нас объекта. Например, ссыл­ка на документ Пpo6a.doc в приложении Word будет выгля­деть следующим образом:

Application . Documents ("Пpo6a.doc")

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

В языке Visual Basic объекты характеризуются не только свойствами и методами, но и событиями . Событие представляет собой действие, распознаваемое объектом. Событие может создаваться пользователем (например, нажатие кнопки мыши или клавиши на клавиатуре) или быть результатом работы других объектов приложения.

Для каждого события можно запрограммировать отклик, то есть реакцию объекта на произошедшее событие. Такая программа называется событийной процедурой . Имя событийной процедуры принято составлять из имени объекта и имени события. Например, для объекта «кнопка» с именем Command 1 и события Click («нажатие», которое наступает, когда мы наводим с помощью мыши стрелку курсора на изображение кнопки и нажимаем левую кнопку мыши) событийная процедура получит имяCommand 1_ Click .

В событийной процедуре может участвовать несколько объектов. Например, в упомянутой выше процедуре Command 1_ Click может присутствовать команда

Text 1. Text = “Привет!”,

в результате выполнения которой в объекте «текстовое поле» с именем Text 1 появится строка со словом «Привет!».

Визуальное программирование, методы которого используются средой разработки Visual Basic позволяет создавать графический интерфейс разрабатываемых приложений на основе использования управляющих элементов, к котором относятся кнопки (CommandButton), флажки (CheckBox) , текстовые поля (TextBox), поля со списком (ListBox) и другие. Эти объекты, их свойства и методы будут рассмотрены в следующем разделе. Пока лишь отметим, что управляющие элементы чаще всего используются для получения от пользователя данных и вывода результатов работы приложения. Таким образом, управляющие элементы являются основой для построения пользовательского интерфейса приложения.

Основными объектами, используемыми при визуальном программировании, являются формы (Form). Форма представляет собой окно, на котором размещаются управляющие элементы. Форма также представляет собой объект, характеризуемый набором свойств и методов. Как и для любого другого объекта для формы можно написать событийную процедуру, например Form _ Load , которая запускается при наступлении события Load («загрузка») и в результате работы которой будут выполнены инструкции, необходимые для работы запускаемого приложения.

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

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

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

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

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

Основные концепции ООП

Объектно-ориентированное программирование или ООП (object-oriented programming) - методология программирования , основанная на представлении программы в виде совокупности объектов , каждый из которых является реализацией определенного типа , использующая механизм пересылки сообщений и классы , организованные в иерархию наследования .

Центральный элемент ООП - абстракция . Данные с помощью абстракции преобразуются в объекты, а последовательность обработки этих данных превращается в набор сообщений, передаваемых между этими объектами. Каждый из объектов имеет свое собственное уникальное поведение. С объектами можно обращаться как с конкретными сущностями, которые реагируют на сообщения, приказывающие им выполнить какие-то действия.

ООП характеризуется следующими принципами ( по Алану Кею):

  • все является объектом ;
  • вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие; объекты взаимодействуют, посылая и получая сообщения ; сообщение - это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия;
  • каждый объект имеет независимую память , которая состоит из других объектов ;
  • каждый объект является представителем класса , который выражает общие свойства объектов данного типа ;
  • в классе задается функциональность (поведение объекта); тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия;
  • классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования ; память и поведение, связанное с экземплярами определенного класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве.

Определение 10.1 . Абстрагирование (abstraction) - метод решения задачи, при котором объекты разного рода объединяются общим понятием (концепцией), а затем сгруппированные сущности рассматриваются как элементы единой категории.

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

Определение 10.2 . Инкапсуляция (encapsulation) - техника, при которой несущественная с точки зрения интерфейса объекта информация прячется внутри него.

Определение 10.3 . Наследование (inheritance) - свойство объектов, посредством которого экземпляры класса получают доступ к данным и методам классов-предков без их повторного определения.

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

Определение 10.4 .

Общая информация

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

Основные принципы ООП

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

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

Полиморфизм

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

Языки ООП

Принципы ООП используются в таких наиболее популярных языках программирования, как C++ и Java, на которых разработана значительная часть программ и приложений. Есть и менее используемые языки ООП - это Delphi, Object Pascal, Ruby и многие другие.

Критика ООП

Несмотря на в основном позитивные высказывания в сторону данной методологии, нередко принципы ООП подвергаются и критике. Как и у у ООП есть свои недостатки.

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

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

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

Привет! Ты когда-нибудь задумывался, почему Java устроена именно так, как она устроена? В том смысле, что ты создаешь классы, на их основе - объекты, у классов есть методы и т.д. Но почему структура языка такова, что программы состоят именно из классов и объектов, а не из чего-то другого? Зачем было придумано понятие «объект » и поставлено во главу угла? Все ли языки устроены так и, если нет, какие преимущества это дает Java? Вопросов, как видишь, много:) Попробуем ответить на каждый из них в сегодняшней лекции.

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

Конечно, Java не просто так состоит из объектов и классов. Это не прихоть ее создателей, и даже не их изобретение. Есть множество других языков, в основе которых лежат объекты. Первый такой язык назывался Simula , и его изобрели еще в 1960-х годах в Норвегии. Помимо всего прочего, в Simula появились понятия «класс » и «метод ». Кристен Нюгор и Оле Йохан Даль - создатели Simula

Казалось бы, Simula - древний язык по меркам программирования, но их «родственную» связь с Java видно невооруженным глазом. Скорее всего, ты легко прочтешь написанный на нем код и в общих чертах объяснишь, что он делает:) Begin Class Rectangle (Width, Height) ; Real Width, Height; Begin Real Area, Perimeter; Procedure Update; Begin Area : = Width * Height; OutText ("Rectangle is updating, Area = " ) ; OutFix (Area, 2 , 8 ) ; OutImage; Perimeter : = 2 * (Width + Height) ; OutText ("Rectangle is updating, Perimeter = " ) ; OutFix (Perimeter, 2 , 8 ) ; OutImage; End of Update; Update; OutText ("Rectangle created: " ) ; OutFix (Width, 2 , 6 ) ; OutFix (Height, 2 , 6 ) ; OutImage; End of Rectangle; Rectangle Class ColouredRectangle (Color) ; Text Color; Begin OutText ("ColouredRectangle created, color = " ) ; OutText (Color) ; OutImage; End of ColouredRectangle; Ref (Rectangle) Cr; Cr : - New ColouredRectangle (10 , 20 , "Green" ) ; End; Пример кода взят из статьи Simula - 50 лет ООП . Как видишь, Java и его предок не так уж сильно отличаются друг от друга:) Это связано с тем, что появление Simula ознаменовало собой рождение новой концепции - объектно-ориентированного программирования . Википедия дает такое определение ООП: Объе́ктно-ориенти́рованное программи́рование (ООП) - методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования. Оно, на мой взгляд, очень удачное. Ты недавно начал изучать Java, но в нем вряд ли найдутся незнакомые тебе слова:) Сегодня ООП - самая распространенная методология программирования. Помимо Java используются во многих популярных языках, о которых ты, возможно, слышал. Это C++ (его активно применяют разработчики компьютерных игр), Objective-C и Swift (на них пишут программы для устройств Apple), Python (наиболее востребован в машинном обучении), PHP (один из самых популярных языков веб-разработки), JavaScript (проще сказать, чего на нем не делают) и многие другие. Собственно говоря, что это за «принципы» ООП? Расскажем подробнее.

Принципы ООП

Это основа основ. 4 главные особенности, которые вместе образуют парадигму объектно-ориентированного программирования. Их понимание - ключ к становлению успешного программиста.

Принцип 1. Наследование.

Хорошая новость: с некоторыми из принципов ООП ты уже знаком! :) Наследование нам уже пару раз встречалось в лекциях, и мы успели с ним поработать. Наследование - механизм, который позволяет описать новый класс на основе существующего (родительского). При этом свойства и функциональность родительского класса заимствуются новым классом. Для чего нужно наследование и какие преимущества оно дает? Прежде всего - повторное использование кода. Поля и методы, описанные в родительских классах, можно использовать в классах-потомках. Если у всех типов автомобилей есть 10 общих полей и 5 одинаковых методов, тебе достаточно вынести их в родительский класс Auto . Ты сможешь использовать их в классах-потомках безо всяких проблем. Сплошные плюсы: и количественно (меньше кода), и, как следствие, качественно (классы становятся гораздо проще). При этом механизм наследования очень гибкий, и недостающую в потомках функциональность ты можешь дописать отдельно (какие-то специфические для конкретного класса поля или поведение). В общем, как и в обычной жизни: все мы чем-то похожи на наших родителей, а чем-то отличаемся от них:)

Принцип 2. Абстракция

Это очень простой принцип. Абстракция означает выделение главных, наиболее значимых характеристик предмета и наоборот - отбрасывание второстепенных, незначительных. Не будем изобретать велосипед и вспомним пример из старой лекции про классы. Скажем, мы создаем картотеку работников компании. Для создания объектов «работник» мы написали класс Employee . Какие характеристики важны для их описания в картотеке компании? ФИО , дата рождения , номер социального страхования , ИНН . Но вряд ли в карточке такого типа нам нужны его рост, цвет глаз и волос. Компании эта информация о сотруднике ни к чему. Поэтому для класса Employee мы зададим переменные String name , int age , int socialInsuranceNumber и int taxNumber , а от лишней для нас информации вроде цвета глаз откажемся, абстрагируемся. А вот если мы создаем картотеку фотомоделей для агентства, ситуация резко меняется. Для описания фотомодели нам как раз очень важны рост , цвет глаз и цвет волос , а номер ИНН не нужен. Поэтому в классе Model мы создаем переменные String height , String hair , String eyes .

Принцип 3. Инкапсуляция

С ним мы уже сталкивались. Инкапсуляция в Java означает ограничение доступа к данным и возможностям их изменения. Как видишь, в его основе лежит слово «капсула». В эту «капсулу» мы прячем какие-то важные для нас данные, которые не хотим, чтобы кто-то менял. Простой пример из жизни. У тебя есть имя и фамилия. Их знают все твои знакомые. Но у них нет доступа к изменению твоего имени и фамилии. Этот процесс, можно сказать, «инкапсулирован» в паспортном столе: поменять имя фамилию можно только там, и сделать это можешь только ты. Остальные «пользователи» имеют доступ к твоему имени и фамилии «только на чтение»:) Еще один пример - деньги в твоей квартире. Оставлять их на виду посреди комнаты - не лучшая идея. Любой «пользователь» (человек, пришедший к тебе домой) сможет изменить число твоих денег, т.е. забрать их. Лучше инкапсулировать их в сейфе. Доступ будет только у тебя и только по специальному коду. Очевидные примеры инкапсуляции, с которыми ты уже работал, - это модификаторы доступа (private , public и т.д.), а также геттеры-сеттеры. Если поле age у класса Cat не инкапсулировать, кто угодно сможет написать: Cat. age = - 1000 ; А механизм инкапсуляции позволяет нам защитить поле age при помощи метода-сеттера, в который мы можем поместить проверку того, что возраст не может быть отрицательным числом.

Принцип 4. Полиморфизм

Полиморфизм - это возможность работать с несколькими типами так, будто это один и тот же тип. При этом поведение объектов будет разным в зависимости от типа, к которому они принадлежат. Звучит сложновато? Сейчас разберемся. Возьмем самый простой пример - животных. Создадим класс Animal с единственным методом - voice() , и двух его наследников - Cat и Dog . public class Animal { public void voice () { System. out. println ("Голос!" ) ; } } public class Dog extends Animal { @Override public void voice () { System. out. println ("Гав-гав!" ) ; } } public class Cat extends Animal { @Override public void voice () { System. out. println ("Мяу!" ) ; } } Теперь попробуем создать ссылку Animal и присвоить ей объект Dog . public class Main { public static void main (String args) { Animal dog = new Dog () ; dog. voice () ; } } Как ты думаешь, какой метод будет вызван? Animal.voice() или Dog.voice() ? Будет вызван метод класса Dog : Гав-гав! Мы создали ссылку Animal , но объект ведет себя как Dog . При необходимости он может вести себя как кошка, лошадь или другое животное. Главное - присвоить ссылке общего типа Animal объект конкретного класса-наследника. Это логично, ведь все собаки являются животными. Именно это мы имели в виду, когда говорили «поведение объектов будет разным, в зависимости от того, к какому типу они принадлежат». Если бы мы создали объект Cat - public static void main (String args) { Animal cat = new Cat () ; cat. voice () ; } метод voice() вывел бы «Мяу! ». А что значит «возможность работать с несколькими типами так, как будто это один и тот же тип»? Это тоже довольно легко. Давайте представим, что мы создаем парикмахерскую для животных. В нашей парикмахерской должны уметь стричь всех животных, поэтому мы создадим метод shear() («постричь») с параметром Animal - животным, которое мы будем стричь. public class AnimalBarbershop { public void shear (Animal animal) { System. out. println ("Стрижка готова!" ) ; } } И теперь мы можем передавать в метод shear и объекты Cat , и объекты Dog ! public static void main (String args) { Cat cat = new Cat () ; Dog dog = new Dog () ; AnimalBarbershop barbershop = new AnimalBarbershop () ; barbershop. shear (cat) ; barbershop. shear (dog) ; } Вот и наглядный пример: класс AnimalBarbershop работает с типами Cat и Dog так, как будто это один и тот же тип. При этом у Cat и Dog разное поведение: они по-разному подают голос.

Причины появления ООП

Почему вообще возникла эта новая концепция программирования - ООП ? У программистов были работающие инструменты: например, процедурные языки. Что же побудило их изобретать что-то принципиально новое? Прежде всего, усложнение задач, которые перед ними стояли. Если 60 лет назад задача программиста выглядела как «вычислить математическое уравнение такое-то», сейчас она может звучать как «реализовать 7 различных концовок для игры S.T.A.L.K.E.R. в зависимости от того, какие решения принимал пользователь в игровых моментах A, B, C , D, E, F и комбинаций этих решений». Задачи, как видишь, за прошедшие десятилетия явно усложнились. А значит, усложнились и типы данных. Это еще одна причина возникновения ООП. Пример с уравнением легко можно решить с помощью обычных примитивов, никаких объектов тут не надо. А вот задачу с концовками игры сложно будет даже описать, не используя каких-то придуманных тобой же классов. Но при этом описать ее в классах и объектах достаточно легко: нам явно будет нужен класс Игра , класс Сталкер , класс Концовка , класс РешениеИгрока , класс ИгровойМомент и так далее. То есть даже не приступив к решению задачи, мы в голове можем легко представить «наброски» ее решения. Усложнение задач поставило программистов перед необходимостью делить задачу на части. Но в процедурном программировании сделать это было не так просто. И очень часто программа представляла собой «дерево» из кучи веток со всеми возможными вариантами ее работы. В зависимости от каких-то условий, программа выполнялась по той или иной ветке. Для небольших программ такой вариант был удобен, но поделить на части объемную задачу было очень сложно. Эта необходимость стала еще одной причиной возникновения ООП. Эта концепция предоставила программистам возможность делить программу на кучу «модулей»-классов, каждый из которых делает свою часть работы. Все объекты, взаимодействуя между собой, образуют работу нашей программы. Кроме того, написанный нами код можно повторно использовать в другом месте программы, что также экономит большое количество времени. English version of this post:

Наверное, в половине вакансий(если не больше), требуется знание и понимание ООП. Да, эта методология, однозначно, покорила многих программистов! Обычно понимание ООП приходит с опытом, поскольку годных и доступно изложенных материалов на данный счет практически нет. А если даже и есть, то далеко не факт, что на них наткнутся читатели. Надеюсь, у меня получится объяснить принципы этой замечательной методологии, как говорится, на пальцах.

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

ООП (или объектно-ориентированное программирование) представляет собой способ организации кода программы, когда основными строительными блоками программы являются объекты и классы, а логика работы программы построена на их взаимодействии.


Об объектах и классах

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

Допустим, нам нужно написать программу, рассчитывающую периметр и площадь треугольника, который задан двумя сторонами и углом между ними. Для написания такой программы используя ООП, нам необходимо будет создать класс (то есть структуру) Треугольник. Класс Треугольник будет хранить три поля (три переменные): сторона А, сторона Б, угол между ними; и два метода (две функции): посчитать периметр, посчитать площадь. Данным классом мы можем описать любой треугольник и вычислить периметр и площадь. Так вот, конкретный треугольник с конкретными сторонами и углом между ними будет называться экземпляром класса Треугольник. Таким образом класс - это шаблон, а экземпляр - конкретная реализация шаблона. А вот уже экземпляры являются объектами, то есть конкретными элементами, хранящими конкретные значения.

Одним из самых распространенных объектно-ориентированных языков программирования является язык java. Там без использования объектов просто не обойтись. Вот как будет выглядеть код класса, описывающего треугольник на этом языке:

/** * Класс Треугольник. */ class Triangle { /** * Специальный метод, называемый конструктор класса. * Принимает на вход три параметра: * длина стороны А, длина стороны Б, * угол между этими сторонами(в градусах) */ Triangle(double sideA, double sideB, double angleAB) { this.sideA = sideA; this.sideB = sideB; this.angleAB = angleAB; } double sideA; //Поле класса, хранит значение стороны А в описываемом треугольнике double sideB; //Поле класса, хранит значение стороны Б в описываемом треугольнике double angleAB; //Поле класса, хранит угла(в градусах) между двумя сторонами в описываемом треугольнике /** * Метод класса, который рассчитывает площадь треугольника */ double getSquare() { double square = this.sideA * this.sideB * Math.sin(this.angleAB * Math.PI / 180); return square; } /** * Метод класса, который рассчитывает периметр треугольника */ double getPerimeter() { double sideC = Math.sqrt(Math.pow(this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos(this.angleAB * Math.PI / 180)); double perimeter = this.sideA + this.sideB + sideC; return perimeter; } }

Если мы внутрь класса добавим следующий код:

/** * Именно в этом месте запускается программа */ public static void main(String args) { //Значения 5, 17, 35 попадают в конструктор класса Triangle Triangle triangle1 = new Triangle(5, 17, 35); System.out.println("Площадь треугольника1: "+triangle1.getSquare()); System.out.println("Периметр треугольника1: "+triangle1.getPerimeter()); //Значения 6, 8, 60 попадают в конструктор класса Triangle Triangle triangle2 = new Triangle(6, 8, 60); System.out.println("Площадь треугольника1: "+triangle2.getSquare()); System.out.println("Периметр треугольника1: "+triangle2.getPerimeter()); }

то программу уже можно будет запускать на выполнение. Это особенность языка java. Если в классе есть такой метод

Public static void main(String args)

то этот класс можно выполнять. Разберем код подробнее. Начнем со строки

Triangle triangle1 = new Triangle(5, 17, 35);

Здесь мы создаем экземпляр triangle1 класса Triangle и тут же задаем ему параметры сторон и угла между ними. При этом, вызывается специальный метод, называемый конструктор и заполняет поля объекта переданными значениями в конструктор. Ну, а строки

System.out.println("Площадь треугольника1: "+triangle1.getSquare()); System.out.println("Периметр треугольника1: "+triangle1.getPerimeter());

выводят рассчитанные площадь треугольника и его периметр в консоль.

Аналогично все происходит и для второго экземпляра класса Triangle .

Понимание сути классов и конструирования конкретных объектов - это уверенный первый шаг к пониманию методологии ООП.

Еще раз, самое важное:

ООП - это способ организации кода программы;

Класс - это пользовательская структура данных, которая воедино объединяет данные и функции для работы с ними(поля класса и методы класса);

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


Три волшебных слова

ООП включает три ключевых подхода: наследование, инкапсуляцию и полиморфизм. Для начала, приведу определения из wikipedia :

Инкапсуляция - свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Некоторые языки (например, С++) отождествляют инкапсуляцию с сокрытием, но большинство (Smalltalk, Eiffel, OCaml) различают эти понятия.

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

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

Понять, что же все эти определения означают на деле достаточно сложно. В специализированных книгах, раскрывающих данную тему на каждое определение, зачастую, отводится целая глава, но, как минимум, абзац. Хотя, сути того, что нужно понять и отпечатать навсегда в своем мозге программиста совсем немного.
А примером для разбора нам будут служить фигуры на плоскости. Из школьной геометрии мы знаем, что у всех фигур, описанных на плоскости, можно рассчитать периметр и площадь. Например, для точки оба параметра равны нулю. Для отрезка мы можем вычислить лишь периметр. А для квадрата, прямоугольника или треугольника - и то, и другое. Сейчас же мы опишем эту задачу в терминах ООП. Также не лишним будет уловить цепь рассуждений, которые выливаются в иерархию классов, которая, в свою очередь, воплощается в работающий код. Поехали:


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

/** * Класс точки. Базовый класс */ class Point { /** * Пустой конструктор */ Point() {} /** * Метод класса, который рассчитывает площадь фигуры */ double getSquare() { return 0; } /** * Метод класса, который рассчитывает периметр фигуры */ double getPerimeter() { return 0; } /** * Метод класса, возвращающий описание фигуры */ String getDescription() { return "Точка"; } }

У получившегося класса Point пустой конструктор, поскольку в данном примере мы работаем без конкретных координат, а оперируем только параметрами значениями сторон. Так как у точки нет никаких сторон, то и передавать ей никаких параметров не надо. Также заметим, что класс имеет методы Point::getSquare() и Point::getPerimeter() для расчета площади и периметра, оба возвращают 0. Для точки оно и логично.


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

/** * Класс Отрезок */ class LineSegment extends Point { LineSegment(double segmentLength) { this.segmentLength = segmentLength; } double segmentLength; // Длина отрезка /** * Переопределенный метод класса, который рассчитывает площадь отрезка */ double getSquare() { return 0; } /** * Переопределенный метод класса, который рассчитывает периметр отрезка */ double getPerimeter() { return this.segmentLength; } String getDescription() { return "Отрезок длиной: " + this.segmentLength; } }

Class LineSegment extends Point

означает, что класс LineSegment наследуется от класса Point . Методы LineSegment::getSquare() и LineSegment::getPerimeter() переопределяют соответствующие методы базового класса. Площадь отрезка всегда равняется нулю, а площадь периметра равняется длине этого отрезка.

Теперь, подобно классу отрезка, опишем класс треугольника(который также наследуется от класса точки):

/** * Класс Треугольник. */ class Triangle extends Point { /** * Конструктор класса. Принимает на вход три параметра: * длина стороны А, длина стороны Б, * угол между этими сторонами(в градусах) */ Triangle(double sideA, double sideB, double angleAB) { this.sideA = sideA; this.sideB = sideB; this.angleAB = angleAB; } double sideA; //Поле класса, хранит значение стороны А в описываемом треугольнике double sideB; //Поле класса, хранит значение стороны Б в описываемом треугольнике double angleAB; //Поле класса, хранит угла(в градусах) между двумя сторонами в описываемом треугольнике /** * Метод класса, который рассчитывает площадь треугольника */ double getSquare() { double square = (this.sideA * this.sideB * Math.sin(this.angleAB * Math.PI / 180))/2; return square; } /** * Метод класса, который рассчитывает периметр треугольника */ double getPerimeter() { double sideC = Math.sqrt(Math.pow(this.sideA, 2) + Math.pow(this.sideB, 2) - 2 * this.sideA * this.sideB * Math.cos(this.angleAB * Math.PI / 180)); double perimeter = this.sideA + this.sideB + sideC; return perimeter; } String getDescription() { return "Треугольник со сторонами: " + this.sideA + ", " + this.sideB + " и углом между ними: " + this.angleAB; } }

Тут нет ничего нового. Также, методы Triangle::getSquare() и Triangle::getPerimeter() переопределяют соответствующие методы базового класса.
Ну а теперь, собственно, тот самый код, который показывает волшебство полиморифзма и раскрывает мощь ООП:

Class Main { /** * Именно в этом месте запускается программа */ public static void main(String args) { //ArrayList - Это специальная структура данных в java, // позволяющая хранить объекты определенного типа в массиве. ArrayList figures = new ArrayList(); //добавляем три разных объекта в массив figures figures.add(new Point()); figures.add(new LineSegment(133)); figures.add(new Triangle(10, 17, 55)); for (int i = 0; i

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


Теперь о инкапсуляции. То, что мы поместили в одном классе параметры фигуры и методы расчета площади и периметра - это и есть инкапсуляция, мы инкапсулировали фигуры в отдельные классы. То, что у нас для расчета периметра используется специальный метод в классе - это и есть инкапсуляцию, мы инкапсулировали расчет периметра в метод getPerimiter() . Иначе говоря, инкапсуляция - это сокрытие реализции (пожалуй, самое короткое, и в то же время емкое определением инкапсуляции).


Полный код примера:

Import java.util.ArrayList; class Main { /** * Именно в этом месте запускается программа */ public static void main(String args) { //ArrayList - Это специальная структура данных в java, // позволяющая хранить объекты определенного типа в массиве. ArrayList figures = new ArrayList(); //добавляем три разных объекта в массив figures figures.add(new Point()); figures.add(new LineSegment(133)); figures.add(new Triangle(10, 17, 55)); for (int i = 0; i

Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter
ПОДЕЛИТЬСЯ:
Компьютеры и современные гаджеты