Планирование уроков на учебный год (по учебнику К.Ю. Полякова, Е.А. Еремина, полный углублённый курс, по 4 часа в неделю)



Урок 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') ; {изменение цвета) 
writeln( 'цвет пера:	pen.getColor );
		{получение цвета)

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

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



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






Наверх