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

Как называется скрытие внутреннего устройства объектов

  • автор:

Как называется скрытие внутреннего устройства объектов

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

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

Объект – это некоторая структура, соответствующая объекту реального мира, его поведению.

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

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

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

В настоящее время методология объектно-ориентированного программирования используется в ряде языков высокого уровня, например, в Java , Си++ и Visual Basic , в интегрированных средах, например, в Delphi .

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

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

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

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

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

Объект совокупность свойств (параметров) определенных сущностей и методов их обработки (программных средств).

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

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

Одним из свойств объекта являются метод его обработки.

Метод программа действий над объектом или его свойствами.

Метод рассматривается как программный код, связанный с определенным объектом; осуществляет преобразование свойств, изменяет поведение объекта.

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

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

Объекты могут объединяться в классы (группы или наборы — в различных программных системах возможна другая терминология).

Методы построения классов

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

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

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

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

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

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

Принципы объектного подхода:

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

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

полиморфизм.

Выделено четыре этапа объектно-ориентированного проектирования:

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

разработка структуры классов, описывающей связь между классами и объектами;

разработка диаграмм объектов, показывающих взаимосвязи с другими объектами;

разработка внутренней структуры программного продукта.

ЗНАКОМСТВО С ЯЗЫКОМ

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

Идея объекта очень проста — рассматривать данные и функции, которые эти данные обрабатывают, как одно целое.

понятие объекта

Объект — это единая конструкция, содержащая в себе набор данных и функций или, в терминологии JavaScript, набор свойств и методов.

функция = метод
переменная = свойство

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

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

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

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

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

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

объект и экземпляр объекта

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

То же и в программировании. Объект — это шаблон, документация. Экземпляр объекта — это рабочая копия.

интерфейс объекта и внутреннее устройство объекта

Программист Сидоров придумал новый объект Rectangle . Он сообщил коллегам следующую информацию.

Объект Rectangle Объект служит для работы с прямоугольниками. Для создания экземпляра объекта нужно написать:

var x = new Rectangle(a,b);

Переменная x теперь является экземпляром объекта Rectangle . Выражения a и b задают ширину и высоту прямоугольника. Конструкция new используется для создания экземпляра.

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

свойства описание
width Ширина прямоугольника
height Высота прямоугольника

методы описание
square() Площадь прямоугольника
perimeter() Периметр прямоугольника
radius() Радиус описанной окружности

var x = new Rectangle(3,4); // Вычисление площади. var s = x.square(); // Вычисление периметра. var p = x.perimeter(); // Вычисление радиуса описанной окружности. var r = x.radius(); // Вычисление максимального размера. var m = x.width; if (x.height > m) m = x.height

Что сообщил Сидоров коллегам? Он сообщил интерфейс своего объекта, то есть информацию, необходимую для взаимодействия с объектом.

Сидоров не показал друзьям программные коды функций square , perimeter , radius . Не сказал он и о вспомогательной функции sqrt , которая была написана для вычисления квадратного корня (эту функцию использует у Сидорова метод radius ). Не сказал Сидоров и про переменную temp , которая потребовалась объекту для промежуточных вычислений.

Другими словами, Сидоров не показал внутреннее устройство своего объекта. Да и зачем коллегам знать это? Сидоров — программист хороший, все свои коды тщательно проверяет, значит, можно пользоваться только интерфейсом, не заглядывая к Сидорову на “кухню”.

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

Внутреннее устройство объекта — это описание переменных и функций внутри объекта на языке программирования (“кухня” Сидорова).

Аналогия с телевизором: интерфейс — это пульт управления. Внутреннее устройство — это электронные “потроха” в ящике.

встроенные объекты и объекты пользователя

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

JavaScript позволяет программировать новые объекты и менять алгоритм работы встроенных. Это очень удобно и привлекательно для программиста. Далее в книге будет много примеров на эту тему, но сначала рассмотрим работу нескольких встроенных объектов (более подробный список приводится в справочном разделе в конце книги).

объект Date

Начнем практическое рассмотрение встроенных объектов языка JavaScript с очень полезного объекта Date . Этот объект используется для работы с датой и временем.

Для создания экземпляра объекта (не только объекта Date, но и любого другого) в языке JavaScript используется ключевое слово new :

var now = new Date();

Теперь переменная now является экземпляром объекта Date и содержит текущую дату и время.

В общем случае экземпляр образуется следующим образом:

var переменная = new Date(параметры);

Возможно указание следующих параметров:

Параметры Пример Описание Пусто.

var now = new Date();

Экземпляр now содержит текущую дату и время. Целочисленные значения для года, месяца и дня.

var birthday = new Date(1954,1,8);

Экземпляр birthday содержит дату, равную 8 февраля 1954 года (нумерация месяцев начинается с нуля). Целочисленные значения для года, месяца, дня, часа, минуты, секунды.

var bell = new Date(2003,0,14,12,20,0);

Экземпляр bell содержит дату и время, равные 12 часам 20 минутам 14 января 2003 года.

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

Имя метода объекта (вспомним, что метод в терминологии JavaScript — это функция) отделяется от имени экземпляра точкой.

var year = bell.getYear();

Переменная year получит значение 2003.

Рассмотрим несколько простых скриптов с объектом Date .

текущая дата и время

<SCRIPT language=JavaScript> var now = new Date(); alert("Сегодн\я: "+now.getDate()+"/"+(now.getMonth()+1)+"/"+ now.getYear()+"\n"+ "Сейчас: "+now.getHours()+":"+now.getMinutes()); //--> SCRIPT>

число дней с начала года

<SCRIPT language=JavaScript> var now = new Date(); // Начало текущего года. var begin = new Date(now.getYear(),0,1); // Число миллисекунд от начала года. var d = now.getTime() - begin.getTime(); // Число миллисекунд в дне. var msPerDay = 24*60*60*1000; // Поделим на количество миллисекунд в сутках. d /= msPerDay; // Покажем результат. alert("Прошло " + Math.floor(d) + " дней с начала года"); //--> SCRIPT>

Замечание о записи Math.floor(x). Встроенный объект Math предлагает различные математические функции и константы. Особенность этого объекта в том, что он существует в единственном экземпляре, который имеет то же имя Math . Программист не может создавать новые экземпляры этого объекта. Правда, в этом и нет необходимости. Метод floor(x) объекта Math возвращает ближайшее целое число, меньшее или равное аргументу (смотрите методы и свойства объекта Math в справочнике).

объект Array

Этот объект предназначен создания массивов данных. Массив — это упорядоченный набор элементов. Доступ к отдельному элементу производится по имени и индексу (номеру). Нумерация элементов в JavaScript начинается с нуля.

пример: массив названий дней недели

dayNames = new Array("воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота");

Для доступа к отдельным элементам массива используют конструкцию:

имя_массива[индекс]

пример: показ текущей даты и времени

<SCRIPT language=JavaScript> var monthNames = new Array("\январ\я", "феврал\я", "марта", "апрел\я", "ма\я", "июн\я", "июл\я", "августа", "сент\ябр\я", "окт\ябр\я", "но\ябр\я", "декабр\я"); // Название дней недели. var dayNames = new Array("воскресенье", "понедельник", "вторник", "среда", "четверг", "п\ятница", "суббота"); // Текущая дата и время. var toDay = new Date(); // Формирование строки вывода. var str = "Cегодня: "; // Добавим в строку день месяца. str += toDay.getDate() + " "; // Добавим в строку название месяца. str += monthNames[toDay.getMonth()] + " "; // Добавим в строку год. str += toDay.getYear() + " года, "; // Добавим день недели. str += dayNames[toDay.GetDay()] + "\n"; // Добавим время. str += "Сейчас: " + toDay.getHours() + ":" + toDay.getMinutes() + ":" + toDay.getSeconds(); // Покажем строку. alert(str); //--> SCRIPT>

Длина массива (число элементов в нем) может меняться во время работы программы:

var f = new Array(); // Сейчас массив пуст. f[0] = 1; // В массиве один элемент. f[1] = 1; // В массиве два элемента. f[2] = f[0]+f[1]; // В массиве три элемента. f[5] = 8; // В массиве шесть элементов f[0]. f[5].

пример: максимальный элемент массива

var max = a; for(i=0; iif(set[i] > max) max = set[i]; >

До сих пор мы пользовались методами объектов и еще ни разу — их свойствами.

Вспомним, что свойства объекта — это, в терминологии JavaScript, те интерфейсные переменные, которые доступны пользователю объекта.

На самом деле, конечно, речь не об объекте, а о конкретном экземпляре объекта. Для обращения к свойствам указывается имя экземпляра объекта и через точку — имя свойства, например:

<SCRIPT language=JavaScript> var set = new Array("Горбунков", "Семен", "Семенович"); alert (set.length); //--> SCRIPT>

Свойство length содержит число элементов массива — его длину.

Язык JavaScript допускает много “вольностей” при обращении с объектами. Так, например, можно задать экземпляр массива без ключевого слова new и имени объекта Array :

var set = [1, 4, 9, 16, 25, 36];

Конечно, браузер, просматривая такую запись, все равно создает экземпляр объекта Array, точно такой же, как и при записи:

var set = new Array(1, 4, 9, 16, 25, 36);

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

var title = "Старик, упавший с каланчи";

совершенно эквивалентна записи:

var title = new String("Старик, упавший с каланчи");

Для работы со встроенными объектами JavaScript удобно иметь под рукой справочник. Он приводится в конце этой книги.

Ниже располагаются ссылки на описание свойств и методов встроенных объектов в этом справочнике:

Нажмите кнопку Сброс , затем выберите верные ответы на вопросы.

Нажмите кнопку Сброс , затем приступайте к решению.

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

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

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

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

нижних подчеркиваний, например, self._vozr. В следующем коде показано, что

доступ к закрытому атрибуту внутри объявления класса может быть осуществлен очень просто. Результатом выполнения программы (листинг 157) станет вывод сообщения: «Здравствуйте, я — студент Сергей из Москвы 17».

self.name=name ^Открытые атрибуты self.city=city

self._vozr=vozr #Закрытый атрибут

рпп^»3дравствуйте, я — студент», self.name, «из», self.city, self, vozr) stl=Student(‘Ceprefi’, ‘Москвы’,’17’)

Продемонстрировать ситуацию, когда закрытие атрибута приводит к ограничению доступа к нему из основного кода, можно на следующем примере. Попытка обратиться к атрибуту vozr вне объявления класса Student (т. е. просто из командной строки) приводит к ошибке, в которой сообщается о том, что объект Student не имеет атрибута vozr (рис. 159). Такая же ошибочная ситуация возникнет даже в том случае, если указать атрибут с двумя нижними подчеркиваниями, например, print(stl._vozr).

[A Python 3.5.1 Shell

File Edit SheN Debug Options Window Help

Python 3.5.1 (v3.5.1:37aQ7cee5969, Dec 6 2015, 01:38:43) [MSC v ^ .1900 32 bit (Intel)] on Win32

Type «copyright”, «credits» or «license()» for more information.

RESTART: C:/Users/Cepren/AppData/Local/Programs/Python/Python35 -32/My_Project/verstka .py

Здравствуйте, я — студент Сергей из Москвы 17 »> stl=Student(‘Ростислав•,’Москва’,’79 1 )

Traceback (most recent call last) :

«, line 1, in print(stl.vozr)

AttributeError: ‘Student’ object has no attribute ‘vozr’

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

Результат работы программы представлен на рис. 160.

Python 3.5.1 Shell File Edit Shell Debug Options Window Help

Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:43 A I

) [MSC v.1900 32 bit (Intel)] on Win32

Type «copyright”, «credits» or «license()» for more info rmation.

RESTART: C:/Users/Cepreii/AppData/Local/Programs/Python/ Python35-32/My_Project/verstka.py Здравствуйте, я — студент Сергей из Москвы 17 Начнем урок »>

Рис. 160. Результат работы программы. Вызван метод message()

После создания закрытого метода можно продемонстрировать ситуацию, когда из пользовательского кода доступ к такому методу не может быть осуществлен. В частности, обращение к классу Student с указанием метода_talk() вызо

вет исключение AttributeError с сообщением об отсутствии соответствующего атрибута (рис. 161).

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

Давайте получим доступ к закрытому атрибуту в нашей программе, написав

оператор print(stl._Student_vozr), и вызовем закрытый метод, оператором

stl._Student_talk(). Подобная ситуация показана на рис. 162.

File Edit SheJI Debug Options Window Help

Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:33:48) [MSC v.1900 32 bit (Intel)] on Win32

Type rf copyright”, «credits» or «license () » for more information

RESTART: C:/Users/Ceprepi/AppData/Local/Program.s/Python/Python3 5-32/My_Project/verstka.py

Здравствуйте, я — студент Сергей из Москвы 17 Начнем урок

»> print (stl ._Student_vozr)

Рис. 161. Сообщение об ошибке

Рис. 162. Вызов закрытого атрибута и обращение к закрытому методу

После работы над созданием закрытых атрибутов и методов может возникнуть естественный вопрос: «А зачем их делать закрытыми, если доступ к ним все равно имеется?» Ответ можно дать такой: во-первых, случайно воспользоваться закрытым атрибутом или методом не удастся, а, во-вторых, инкапсуляция, т. е. ограничение доступа к методам или переменным, в Python существует на уровне договоренности между программистами, поэтому не стоит стремиться закрывать абсолютно все методы и атрибуты созданного класса.

Урок 91
Скрытие внутреннего устройства
(§49. Скрытие внутреннего устройства)

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

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

Скрытие внутреннего устройства объектов называют инкапсуляцией («помещение в капсулу»).

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

Разберём простой пример. Во многих системах программирования есть класс, описывающий свойства «пера», которое используется при рисовании линий в графическом режиме. Назовём этот класс ТРеn, в простейшем варианте он будет содержать только одно поле Color, которое определяет цвет. Будем хранить код цвета в виде символьной строки, в которой записан шестнадцатеричный код составляющих модели RGB. Например, ’FFOOFF’ — это фиолетовый цвет, потому что красная (R) и синяя (В) составляющие равны FF16 = 255, а зелёной составляющей нет вообще. Класс можно объявить так:

type ТРеn = class Color: string; end;

По умолчанию все члены класса (поля и методы) открытые, общедоступные (англ. public). Те элементы, которые нужно скрыть, в описании класса помещают в «частный» раздел (англ. private), например, так:

type ТРеn = class private FColor: string; end;

В этом примере поле FColor закрытое. Имена всех закрытых полей далее будем начинать с буквы «F» (от англ. field — поле). К закрытым полям нельзя обратиться извне (это могут делать только методы самого объекта), поэтому теперь невозможно не только изменить внутренние данные объекта, но и просто узнать их значения. Чтобы решить эту проблему, нужно добавить к классу ещё два метода: один из них будет возвращать текущее значение поля FColor, а второй — присваивать полю новое значение. Эти методы доступа назовем getColor (в переводе с англ. — получить Color) и setColor (в переводе с англ. — установить Color):

type TPen=class private FColor: string; public function getColor: string; procedure setColor(newColor: string); end;

Обратите внимание, что оба метода находятся в секции public (общедоступные).

Что же улучшилось по сравнению с первым вариантом (когда поле было открытым)? Согласно принципам ООП, внутренние поля объекта должны быть доступны только с помощью методов. В этом случае внутреннее представление данных может как угодно отличаться от того, как другие объекты «видят» эти данные.

В простейшем случае метод getColor можно написать так:

function TPen.getColor: string; begin Result:=FColor; end;

В методе setColor мы можем обрабатывать ошибки, не разрешая присваивать полю недопустимые значения. Например, установим, что символьная строка с кодом цвета, передаваемая нашему объекту, должна состоять из шести символов. Если эти условия не выполняются, будем записывать в поле FColor код чёрного цвета ’000000’:

procedure TPen.setColor(newColor: string); begin if Length(newColor)<>6 then FColor:='000000' < если ошибка, то чёрный цвет) else FColor:=newColor end;

Теперь если pen — это объект класса TPen, то для установки и чтения его цвета нужно использовать показанные выше методы:

pen.setColor ('FFFF00') ; 

Итак, мы скрыли внутренние данные, но одновременно обращение к свойствам стало выглядеть довольно неуклюже: вместо pen. Color : = 'FFFF00' теперь нужно писать pen . setColor ('FFFF00') . Чтобы упростить запись, во многие объектно-ориентированные языки программирования ввели понятие свойства (англ. property), которое внешне выглядит как переменная объекта, но на самом деле при записи и чтении свойства вызываются методы объекта.

Следующая страница Свойство

Cкачать материалы урока

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

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

https://alkogolizm.vyvod-iz-zapoya-v-stacionare-samara11.ru/