Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Одиноков / МиИПиС_асп_13г / MATLAB R2008a. КЛАССЫ_ЧАСТЬ 3_12г.doc
Скачиваний:
35
Добавлен:
15.04.2015
Размер:
771.58 Кб
Скачать

Interface Guides Class Design (Интерфейс руководит разработкой класса)

Подклассы, выведенные из абстрактного класса графиков, позволяют:

  • Создать инстанцию объекта специализированного графика (объекта подкласса) без его визуализации;

  • Специфицировать любое количество или ни одного свойства, когда вы создаете объект специализированного графика;

  • Обновить автоматически на текущем отображенном графике любое свойство объекта при внесении какого-либо изменения;

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

Defining the Interface (Определение интерфейса)

Класс graph есть абстрактный класс (в этом случае для какого-либо блока methods должен быть явно задан атрибут Abstract как true), который определяет методы и свойства, используемые производными классами. Комментарии в абстрактном классе дают дополнительные рекомендации:

classdef graph < handle % Класс graph предполагает ссылку

% любых копий на исходные данные, поэтому это handle-класс.

% Abstract class for creating data graphs (Абстрактный класс для создания

% графиков данных).

% Subclass constructor should accept the data that is to be plotted and property

% name/property value pairs (Конструктор подкласса должен иметь доступ к

% данным, которые необходимо отобразить, и парам имя/величина для

% свойств).

properties (SetAccess = protected, GetAccess = ...

protected) % Указания на доступ к свойствам

% методами самого класса и его подклассов

% (их объектов).

Primitive % HG primitive handle (Метка Handle Graphics-

% примитива).

AxesHandle % Axes handle (Метка осей) - хранилище

% метки (handle) осей HG-объекта.

end

properties % Public access (Общий доступ).

Data % Данные, подлежащие изображению в виде графика.

end

methods (Abstract)

draw(obj) % Метод (класса graph) создания примитива для

% рисования объекта obj.

% Use a line, surface, or patch HG primitive (Используйте линию,

% поверхность или путь HG -примитива).

zoom(obj,factor) % Метод (класса graph) масштабирования

% для объекта obj, определяемый фактором factor.

% Change the CameraViewAngle for 2D and 3D views use

% camzoom for consistency (Изменяйте CameraViewAngle для

% 2D- и 3D-визуализаций, используя camzoom для слаженности);

% camzoom – стандартная функция масштабирования

% визуальной картинки.

updateGraph(obj) % Graph-метод для обновления графика.

% Called by the set.Data method to update the drawing

% primitive whenever the Data property is changed (Вызывается

% через метод set.Data для обновления рисующего примитива

% при любом изменении свойства Data)

end

methods

function set.Data(obj,newdata) % Set-метод доступа на

% установку свойства Data объекта obj.

obj.Data = newdata; % Установка величины свойства

% Data объекта obj.

updateGraph(obj) % Вызов graph-метода для обновления

% графика на фигуре.

end

methods (Static) % Метод относится только к самому классу

% graph, но не к его инстанциям.

addButtons(obj) % Вызов функции-метода класса graph

% для добавления управляющих кнопок на графике.

end

end

В данном случае класс graph исполняет метод set.Data для управления изменением свойства Data. Альтернативой может быть задание свойства Data как Abstract и разрешение подклассам самим определять метод установки этого свойства. Однако определение общего set-метода доступа, вызывающего другой общий (в данном случае абстрактный) метод updateGraph, исполняемый по-своему каждым подклассом, позволяет графическому интерфейсу более эффективно осуществлять планирование в целой группе классов без ограничения гибкости.

Static Method to Work with All Subclasses (Статический метод для работы со всеми подклассами)

Статический метод addButtons просто добавляет кнопки управления для методов zoom (изменение масштаба графика), которые каждый подкласс должен выполнить. Задание статического метода вместо обычной функции позволяет этому методу иметь доступ к protected-данным (к осям в свойстве AxesHandle) класса. Заметьте, что метод zoom для объекта определен как кнопочный callback-вызов:

function addButtons(gobj) % Функция-метод класса graph % для добавления кнопок на фигуре объекта gobj.

hfig = get(gobj.AxesHandle,'Parent'); % Сохранение

% значения свойства Parent HG-объекта (см. описание

% общей MATLAB-функции get), хранящегося в свойстве

% AxesHandle graph-инстанции gobj, в виде переменной

% hfig.

uicontrol(hfig,'Style','pushbutton',...

'String','Zoom Out','Callback',... @(src,evnt)zoom(gobj,.5)); % Вызов MATLAB-

% функции uicontrol для создания

% управляющей кнопки Zoom Out: значение свойства Style

% объекта hfig устанавливается как 'pushbutton', значение

% свойства String – как 'Zoom Out', значение свойства

% Callback – как @(src,evnt)zoom(gobj,.5)(анонимная

% callback-функция действия, использующая метод zoom

% класса graph с фактором масштабирования .5).

uicontrol(hfig,'Style','pushbutton',...

'String','Zoom In', 'Callback',...

@(src,evnt)zoom(gobj,2),'Position',...

[100 20 60 20]); % Вызов функции

% uicontrol для создания управляющей кнопки

% Zoom In; позиция кнопки на фигуре задана координатами

% [100 20 60 20](свойство Position объекта hfig).

end

Deriving a Concrete Class — linegraph (Определение конкретного класса – linegraph)

Замечание. Отобразите полностью комментированный код для класса linegraph, кликнув связь linegraph class.

Этот пример определяет подкласс, используемый для представления простой линии графика. Он выведен из класса graph, но обеспечивает реализацию абстрактных методов draw, zoom, updateGraph и своего собственного конструктора. Базовый класс graph и рассматриваемый подкласс содержатся в пакете graphics, который должен быть упомянут при ссылке на имя класса:

classdef linegraph < graphics.graph

Adding Properties (Добавление свойств)

Класс linegraph выполняет роль интерфейса, выполненного на базе другого интерфейсного класса (суперкласса) graph с добавлением двух свойств - LineColor и LineType. Этот класс задает начальные величины каждого свойства в случае, если linegraph-объект создается без спецификации этих свойств (такое случается, когда производится перезагрузка объекта из MAT-файла). Спецификация свойств в конструкторе факультативна (не обязательна). Данные требуются для построения графика, но не для создания linegraph-объекта:

properties

LineColor = [0 0 0]; % Цвет линии.

LineType = '-'; % Тип линии.

end

The linegraph Constructor (Linegraph-конструктор)

Конструктор принимает на место первого входного аргумента data структуру с данными координат x и y, а на место второго входного аргумента (массив ячеек) varargin - пары имя/величина свойства:

function gobj = linegraph(data,varargin) % Создание

% linegraph-объекта gobj.

if nargin > 0 % Проверка на наличие аргумента data у

% конструктора. Если так, то:

gobj.Data = data; % Передача данных для построения

% графика в свойство Data объекта gobj.

if nargin > 2 % Проверка на наличие аргумента

% varargin у конструктора. Если так, то:

for k=1:2:length(varargin) % Для нечетных

% элементов varargin{k} (имена) массива

% varargin (длиной length(varargin)) следует

% передача очередных (четных - varargin{k+1})

% элементов (значений) объекту gobj как величин его

% свойств:

gobj.(varargin{k}) = varargin{k+1};

end

end

end

end

Implementing the draw Method (Исполнение draw-метода)

Метод draw класса linegraph использует величины свойств объекта gobj, назначенных linegraph-конструктором, для рисования графика. Handle-указатель (метка) для линии-примитива графика хранится как защищенные данные суперкласса graph. То есть класс linegraph сам не создает рисующий примитив, но отображает график при вызове своего метода draw. Для поддержки случая отсутствия входных аргументов конструктора перед работой draw контролирует свойство Data на предмет наличия данных:

function gobj = draw(gobj)

if isempty(gobj.Data) % Контроль отсутствия данных.

error('The linegraph object contains no ...

data')% Обращение к стандартной функции error

% для вывода сообщения: «Linegraph-объект не содержит

% данных».

end

h = line(gobj.Data.x,gobj.Data.y,...

'Color',gobj.LineColor,...

'LineStyle',gobj.LineType); % Рисующий

% примитив на основе свойств linegraph-

% объекта gobj.

gobj.Primitive = h; % Сохранение метки примитива в

% свойстве Primitive базового класса graph.

gobj.AxesHandle = get(h,'Parent'); % Сохранение

% handle-метки осей (запрошенной у свойства Parent HG-

% примитива h)в свойстве AxesHandle базового класса

% graph.

end