
- •Часть 3
- •Введение
- •Indexing Functions (Индексирующие функции);
- •1 12 3 4 % Данные double-части объекта md.
- •InPutNames % cell array of strings (массив ячеек строк) – имена
- •Interfaces and Abstract Classes (Интерфейсы и абстрактные классы)
- •Interface Properties and Methods (Интерфейс свойств и методов)
- •Interface Guides Class Design (Интерфейс руководит разработкой класса)
- •Implementing the zoom Method (Исполнение метода zoom)
- •Inheritance of Properties (Наследование свойств)
- •Implementing the PostSet Property Event and Listener (Исполнение PostSet-события свойства и слушателя) показывает пример слушателя свойств.
- •Приложение
- •Implementing a Set/Get Interface for Properties (Исполнение set/get-интерфейса для свойств)…....12
- •Indexing Functions (Индексирующие
- •Inheritance of Properties (Наследование событий)…..........................................................................................54
- •Часть3 Редактор р.К. Мангутова
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