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

Присвоение имени событию в определении класса
Запуск события вызовом notify
Включение события свойства через SetObservable признак
Создание прослушивателей для определяемых классами событий и PostSet свойств события
Определение функций обратного вызова прослушивателя, которые принимают дополнительные аргументы
Включение и отключение прослушивателей
The fcneval класс вычисляет выражение MATLAB для заданной области двух переменных. The fcneval является источником данных, которые объектов fcnview класс графика как поверхность. fcneval является источником событий, используемых в этом примере. Список определений классов см. по адресу @ fcneval/fcneval.m Код
| Свойство | Значение | Цель |
|---|---|---|
FofXY | указатель на функцию | Выражение MATLAB (функция двух переменных). |
Lm | двухэлементный вектор | Пределы, над которыми вычисляется функция, в обеих переменных. SetObservable для атрибута задано значение true для включения прослушивателей событий свойств. |
Data | структура с матрицами x, y и z | Данные, следующие из оценки функции. Используется для графика поверхностей. Dependent для атрибута задано значение true, что означает get.Data вызывается метод, чтобы определить значение свойства при запросе, и никакие данные не сохраняются. |
| Событие | При срабатывании |
|---|---|
UpdateGraph | FofXY функция набора свойств (set.FofXY) вызывает notify метод, когда новое значение задано для выражения MATLAB для объекта этого класса. |
| Метод | Цель |
|---|---|
fcneval | Конструктор классов. Входами являются указатель на функцию и двухэлементный вектор, задающий пределы, над которыми можно вычислить функцию. |
set.FofXY | FofXY функция набора свойств. Вызывается каждый раз, когда задано значение свойства, в том числе во время конструкции объекта. |
set.Lm | Lm функция набора свойств. Используется для проверки допустимых пределов. |
get.Data | Data функция получения свойства. Этот метод вычисляет значения для Data свойство всякий раз, когда эти данные запрашиваются (членами класса или внешне). |
grid | Статический метод (Static для атрибута задано значение true) используется при вычислении данных. |
Объекты fcnview класс содержит fcneval объекты как источник данных для четырех поверхностных графиков, созданных в виде функции. fcnview создает прослушиватели и функции обратного вызова, которые реагируют на изменения в данных, содержащихся в fcneval объекты. Список определений классов см. по адресу @ fcnview/fcnview.m Код
| Свойство | Значение | Цель |
|---|---|---|
FcnObject | fcneval объект | Этот объект содержит данные, которые используются для создания графиков функций. |
HAxes | указатель на оси | Каждый образец fcnview объект хранит указатель на оси, содержащую его подграфик. |
HLUpdateGraph | event.listener объект для UpdateGraph событие | Установка event.listener Enabled объекта свойство к true включает прослушиватель; false отключает прослушиватель. |
HLLm | event.listener объект для Lm событие свойства | Установка event.listener Enabled объекта свойство к true включает прослушиватель, false отключает прослушиватель. |
HEnableCm | uimenu указателя | Элемент контекстного меню, используемый для включения прослушивателей (используется для обработки проверенного поведения) |
HDisableCm | uimenu указателя | Элемент контекстного меню, используемый для отключения прослушивателей (используется для управления проверенным поведением) |
HSurface | поверхностный указатель | Используется коллбэками событий для обновления данных о поверхности. |
| Метод | Цель |
|---|---|
fcnview | Конструктор классов. Вход fcneval объект. |
createLisn | Вызовы addlistener чтобы создать прослушиватели для UpdateGraph и Lm свойства PostSet прослушиватели. |
lims | Устанавливает пределы осей к текущему значению fcneval Lm объекта свойство. Используется обработчиками событий. |
updateSurfaceData | Обновление данных поверхности без создания нового объекта. Используется обработчиками событий. |
listenUpdateGraph | Коллбэк для UpdateGraph событие. |
listenLm | Коллбэк для Lm свойства PostSet событие |
delete | Удалите метод для fcnview класс. |
createViews | Статический метод, который создает образец fcnview класс для каждого подграфика, определяет контекстные меню, которые включают/отключают прослушиватели, и создает подграфики |
Оба fcneval и fcnview классы наследуют методы от handle класс. В следующей таблице перечислены только те унаследованные методы, которые используются в этом примере.
Handle Class Methods предоставляет полный список методов, которые наследуются при подклассификации handle класс.
| Методы, унаследованные от класса Handle | Цель |
|---|---|
addlistener | Зарегистрируйте прослушиватель для определенного события и присоедините прослушивателя к определяющему событие объекту. |
notify | Инициируйте событие и уведомляйте всех зарегистрированные прослушиватели. |
В этом разделе описывается, как использовать классы.
Создайте образец fcneval класс, содержащий выражение MATLAB функции двух переменных и области значений, над которой вы хотите вычислить эту функцию
Используйте fcnview статическая функция класса createViews чтобы визуализировать функцию
Измените выражение MATLAB или пределы, содержащиеся в fcneval объект и все fcnview объекты отвечают на сгенерированные события.
Вы создаете fcneval объект путем вызова его конструктора с двумя аргументами - анонимной функцией и двухэлементным, монотонно увеличивающимся вектором. Для примера:
feobject = fcneval(@(x,y) x.*exp(-x.^2-y.^2),[-2 2]);
Используйте createViews статический метод для создания графиков функции. Используйте имя класса для вызова статической функции:
fcnview.createViews(feobject);
The createView метод генерирует четыре представления функции, содержащейся в fcneval объект.

Каждый подграфик задает контекстное меню, которое может включать и отключать прослушиватели, сопоставленные с этим графиком. Например, если вы отключите прослушиватели на подграфике 221 (верхний слева) и измените выражение MATLAB, содержащееся в fcneval объект, только оставшиеся три подграфиков обновляются, когда UpdateGraph событие срабатывает:
feobject.FofXY = @(x,y) x.*exp(-x.^.5-y.^.5);

Точно так же, если вы измените пределы путем присвоения значения feobject.Lm свойство, feobject запускает PostSet событие свойства и коллбэки прослушивателя обновляют график.
feobject.Lm = [-8 3];

На этом рисунке прослушиватели снова активируются через контекстное меню для подграфика 221. Потому что обратный коллбэк прослушивателя для свойства PostSet событие также обновляет данные поверхности, теперь синхронизируются все представления
The UpdateGraph событие происходит, когда представление MATLAB математической функции, содержащейся в fcneval объект изменяется. The fcnview объекты, которые содержат графики, прослушивают это событие, поэтому они могут обновить графики, чтобы представлять новую функцию.
The UpdateGraph событие является событием, заданным классом. The fcneval класс называет событие и вызовы notify когда происходит событие.

The fcnview класс задает прослушиватель для этого события. Когда fcneval запускает событие, fcnview прослушиватель выполняет функцию обратного вызова, которая выполняет следующие действия:
Определяет, хранится ли указатель на объект поверхности в fcnview объект все еще действителен (то есть объект все еще существует)
Обновление поверхностного XData, YData, и ZData путем запроса fcneval Data объекта свойство.
The fcneval класс задает имя события в event блок:
events UpdateGraph end
The fcneval класс определяет метод набора свойств для FofXY свойство. FofXY - свойство, которое хранит выражение MATLAB для математической функции. Это выражение должно быть допустимым выражением MATLAB для функции двух переменных.
The set.FofXY метод:
Определяет пригодность выражения
Если выражение подходит:
Присваивает выражение FofXY свойство
Запускает UpdateGraph событие
Если fcneval.isSuitable не возвращает MException объект, set.FofXY метод присваивает значение свойству и запускает UpdateGraph событие.
function set.FofXY(obj,func) % Determine if function is suitable to create a surface me = fcneval.isSuitable(func); if ~isempty(me) throw(me) end % Assign property value obj.FofXY = func; % Trigger UpdateGraph event notify(obj,'UpdateGraph'); end
The set.FofXY метод вызывает статический метод (fcneval.isSuitable) для определения пригодности указанного выражения. fcneval.isSuitable возвращает MException объект, если он определяет, что выражение непригодно. fcneval.isSuitable вызывает MException конструктор непосредственно для создания более полезных сообщений об ошибке для пользователя.
set.FofXY выдает исключение с помощью throw способ. Выдача исключения прекращает выполнение set.FofXY и препятствует тому, чтобы метод делал присвоение свойству или запускал UpdateGraph событие.
Вот fcneval.isSuitable метод:
function isOk = isSuitable(funcH) v = [1 1;1 1]; % Can the expression except 2 numeric inputs try funcH(v,v); catch %#ok<CTCH> me = MException('DocExample:fcneval',... ['The function ',func2str(funcH),' Is not a suitable F(x,y)']); isOk = me; return end % Does the expression return non-scalar data if isscalar(funcH(v,v)); me = MException('DocExample:fcneval',... ['The function ',func2str(funcH),'' Returns a scalar when evaluated']); isOk = me; return end isOk = []; end
The fcneval.isSuitable метод может обеспечить дополнительный тест, чтобы убедиться, что выражение, назначенное FofXY свойство соответствует критериям, необходимым для проекта класса.
Класс мог реализовать событие набора свойств для FofXY свойство и, следовательно, не нужно было звонить notify (см. «Прослушивание изменений значений свойств»). Определение события класса обеспечивает большую гибкость в этом случае, потому что вы можете лучше управлять срабатыванием события.
Например, предположим, что вы хотели обновить график, только если новые данные отличаются. Если новое выражение дало те же данные в пределах некоторого допуска, set.FofXY метод не смог вызвать событие и избежать обновления графика. Однако метод все еще может задать новое значение свойства.
The fcnview класс создает прослушиватель для UpdateGraph событием с использованием addlistener метод:
obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',... @(src,evnt)listenUpdateGraph(obj,src,evnt)); % Add obj to argument list
The fcnview объект хранит указатель на event.listener объект в своем HLUpdateGraph свойство, которое используется для включения/отключения прослушивателя контекстным меню (см. «Включение и отключение прослушивателей»).
The fcnview объект (obj) добавляется к двум аргументам по умолчанию (src, evnt) передан в обратный коллбэк прослушивателя. Имейте в виду, источник события (src) является fcneval объект, но fcnview объект содержит указатель на объект поверхности, который обновляется коллбэком.
The listenUpdateGraph функция определяется следующим образом:
function listenUpdateGraph(obj,src,evnt) if ishandle(obj.HSurface) % If surface exists obj.updateSurfaceData % Update surface data end end
The updateSurfaceData функция является классом методом, который обновляет данные поверхности, когда другая математическая функция назначена fcneval объект. Обновление данных графического объекта более эффективно, чем создание нового объекта с помощью новых данных:
function updateSurfaceData(obj) % Get data from fcneval object and set surface data set(obj.HSurface,... 'XData',obj.FcnObject.Data.X,... 'YData',obj.FcnObject.Data.Y,... 'ZData',obj.FcnObject.Data.Matrix); end
Все свойства поддерживают предопределенную PostSet событие (для получения дополнительной информации о событиях свойств см. раздел Property-Set и Query Events). Этот пример использует PostSet событие для fcneval
Lm свойство. Это свойство содержит двухэлементный вектор, задающий область значений, в котором вычисляется математическая функция. Сразу после того, как это свойство будет изменено (оператором like obj.Lm = [-3 5];), а fcnview объекты, прослушивающие это событие, обновляют график, чтобы отразить новые данные.

Lm Назначение свойствThe fcneval класс определяет функцию набора для Lm свойство. Когда значение присваивается этому свойству во время конструкции объекта или переназначения свойства, происходит следующая последовательность:
Делается попытка присвоить значение аргумента Lm свойство.
The set.Lm метод выполняется, чтобы проверить, находится ли значение в соответствующей области значений - если да, это делает назначение, если нет, это генерирует ошибку.
Если значение Lm успешно установлен, MATLAB запускает PostSet событие.
Все прослушиватели выполняют свои коллбэки, но порядок недетерминирован.
The PostSet событие не происходит до тех пор, пока не произойдет фактическое присвоение свойства. Функция набора свойств предоставляет возможность справиться с потенциальными ошибками назначения перед PostSet происходит событие.
Чтобы создать прослушиватель для PostSet событие, необходимо задать SetObservable свойства атрибут к true:
properties (SetObservable = true) Lm = [-2*pi 2*pi]; % specifies default value end
MATLAB автоматически запускает событие, поэтому нет необходимости в вызове notify.
Параметр «Задать атрибуты свойств» содержит список всех атрибутов свойств.
The fcnview класс создает прослушиватель для PostSet событием с использованием addlistener метод:
obj.HLLm = addlistener(obj.FcnObject,'Lm','PostSet',... @(src,evnt)listenLm(obj,src,evnt)); % Add obj to argument list
The fcnview объект хранит указатель на event.listener объект в своем HLLm свойство, которое используется для включения/отключения прослушивателя контекстным меню (см. «Включение и отключение прослушивателей»).
The fcnview объект (obj) добавляется к двум аргументам по умолчанию (src, evnt) передан в обратный коллбэк прослушивателя. Имейте в виду, источник события (src) является fcneval объект, но fcnview объект содержит указатель на объект поверхности, который обновляется коллбэком.
Коллбэк устанавливает пределы осей и обновляет данные поверхности, потому что изменение пределов заставляет математическую функцию оцениваться в другой области значений:
function listenLm(obj,src,evnt) if ishandle(obj.HAxes) % If there is an axes lims(obj); % Update its limits if ishandle(obj.HSurface) % If there is a surface obj.updateSurfaceData % Update its data end end end
Каждый fcnview объект хранит указатель на объекты прослушивателя, которые он создает, так что прослушиватели могут быть включены или отключены через контекстное меню после создания графиков. Все прослушиватели являются образцами event.listener класс, который задает свойство под названием Enabled. По умолчанию это свойство имеет значение true, что позволяет прослушивателю. Если вы задаете это свойство равным false, прослушиватель все еще существует, но отключена. Этот пример создает контекстное меню, активное для осей каждого графика, которое предоставляет способ изменить значение Enabled свойство.
В контекстном меню, соответствующем этим двум элементам меню, используются два коллбэков:
Listen - Устанавливает Enabled свойство для обоих UpdateGraph и PostSet прослушиватели true и добавляет галочку рядом с элементом меню Listen.
Don't Listen - Устанавливает Enabled свойство для обоих UpdateGraph и PostSet прослушиватели false и добавляет галочку рядом с элементом меню Don't Listen.
Оба коллбэков включают fcnview объект как аргумент (в дополнение к требуемым аргументам source и event data) для предоставления доступа к указателю на объекты прослушивателя.
The enableLisn функция вызывается, когда пользователь выбирает Listen из контекстного меню.
function enableLisn(obj,src,evnt) obj.HLUpdateGraph.Enabled = true; % Enable listener obj.HLLm.Enabled = true; % Enable listener set(obj.HEnableCm,'Checked','on') % Check Listen set(obj.HDisableCm,'Checked','off') % Uncheck Don't Listen end
The disableLisn функция вызывается, когда пользователь выбирает Don't Listen из контекстного меню.
function disableLisn(obj,src,evnt) obj.HLUpdateGraph.Enabled = false; % Disable listener obj.HLLm.Enabled = false; % Disable listener set(obj.HEnableCm,'Checked','off') % Unheck Listen set(obj.HDisableCm,'Checked','on') % Check Don't Listen end
classdef fcneval < handle properties FofXY end properties (SetObservable = true) Lm = [-2*pi 2*pi] end % properties SetObservable = true properties (Dependent = true) Data end events UpdateGraph end methods function obj = fcneval(fcn_handle,limits) % Constructor returns object if nargin > 0 obj.FofXY = fcn_handle; % Assign property values obj.Lm = limits; end end function set.FofXY(obj,func) me = fcneval.isSuitable(func); if ~isempty(me) throw(me) end obj.FofXY = func; notify(obj,'UpdateGraph'); end function set.Lm(obj,lim) if ~(lim(1) < lim(2)) error('Limits must be monotonically increasing') else obj.Lm = lim; end end function data = get.Data(obj) [x,y] = fcneval.grid(obj.Lm); matrix = obj.FofXY(x,y); data.X = x; data.Y = y; data.Matrix = real(matrix); end end % methods methods (Static = true) function [x,y] = grid(lim) inc = (lim(2)-lim(1))/20; [x,y] = meshgrid(lim(1):inc:lim(2)); end % grid function isOk = isSuitable(funcH) v = [1 1;1 1]; try funcH(v,v); catch %#ok<CTCH> me = MException('DocExample:fcneval',... ['The function ',func2str(funcH),' Is not a suitable F(x,y)']); isOk = me; return end if isscalar(funcH(v,v)); me = MException('DocExample:fcneval',... ['The function ',func2str(funcH),' Returns a scalar when evaluated']); isOk = me; return end isOk = []; end end end
classdef fcnview < handle properties FcnObject % fcneval object HAxes % subplot axes handle HLUpdateGraph % UpdateGraph listener handle HLLm % Lm property PostSet listener handle HEnableCm % "Listen" context menu handle HDisableCm % "Don't Listen" context menu handle HSurface % Surface object handle end methods function obj = fcnview(fcnobj) if nargin > 0 obj.FcnObject = fcnobj; obj.createLisn; end end function createLisn(obj) obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',... @(src,evnt)listenUpdateGraph(obj,src,evnt)); obj.HLLm = addlistener(obj.FcnObject,'Lm','PostSet',... @(src,evnt)listenLm(obj,src,evnt)); end function lims(obj) lmts = obj.FcnObject.Lm; set(obj.HAxes,'XLim',lmts); set(obj.HAxes,'Ylim',lmts); end function updateSurfaceData(obj) data = obj.FcnObject.Data; set(obj.HSurface,... 'XData',data.X,... 'YData',data.Y,... 'ZData',data.Matrix); end function listenUpdateGraph(obj,~,~) if ishandle(obj.HSurface) obj.updateSurfaceData end end function listenLm(obj,~,~) if ishandle(obj.HAxes) lims(obj); if ishandle(obj.HSurface) obj.updateSurfaceData end end end function delete(obj) if ishandle(obj.HAxes) delete(obj.HAxes); else return end end end methods (Static) createViews(a) end end
function createViews(fcnevalobj) p = pi; deg = 180/p; hfig = figure('Visible','off',... 'Toolbar','none'); for k=4:-1:1 fcnviewobj(k) = fcnview(fcnevalobj); axh = subplot(2,2,k); fcnviewobj(k).HAxes = axh; hcm(k) = uicontextmenu; set(axh,'Parent',hfig,... 'FontSize',8,... 'UIContextMenu',hcm(k)) fcnviewobj(k).HEnableCm = uimenu(hcm(k),... 'Label','Listen',... 'Checked','on',... 'Callback',@(src,evnt)enableLisn(fcnviewobj(k),src,evnt)); fcnviewobj(k).HDisableCm = uimenu(hcm(k),... 'Label','Don''t Listen',... 'Checked','off',... 'Callback',@(src,evnt)disableLisn(fcnviewobj(k),src,evnt)); az = p/k*deg; view(axh,az,30) title(axh,['View: ',num2str(az),' 30']) fcnviewobj(k).lims; surfLight(fcnviewobj(k),axh) end set(hfig,'Visible','on') end function surfLight(obj,axh) obj.HSurface = surface(obj.FcnObject.Data.X,... obj.FcnObject.Data.Y,... obj.FcnObject.Data.Matrix,... 'FaceColor',[.8 .8 0],'EdgeColor',[.3 .3 .2],... 'FaceLighting','phong',... 'FaceAlpha',.3,... 'HitTest','off',... 'Parent',axh); lims(obj) camlight left; material shiny; grid off colormap copper end function enableLisn(obj,~,~) obj.HLUpdateGraph.Enabled = true; obj.HLLm.Enabled = true; set(obj.HEnableCm,'Checked','on') set(obj.HDisableCm,'Checked','off') end function disableLisn(obj,~,~) obj.HLUpdateGraph.Enabled = false; obj.HLLm.Enabled = false; set(obj.HEnableCm,'Checked','off') set(obj.HDisableCm,'Checked','on') end