Этот пример задает два класса:
fcneval
— Функциональный класс средства анализа содержит выражение MATLAB® и выполняет это выражение по заданной области
fcnview
— Функциональный класс средства просмотра содержит fcneval
возразите и отображения появляются графики выполненного выражения с помощью данных, содержавшихся в fcneval
.
Этот класс задает два события:
Заданное классом событие, которое происходит, когда новое значение задано для функции MATLAB
Событие свойства, которое происходит, когда свойство, содержащее пределы, изменяется
Следующая схема показывает отношение между двумя объектами. fcnview
объект содержит fcneval
возразите и создает графики из данных, которые это содержит. fcnview
создает прослушиватели, чтобы изменить графики если любые из данных в fcneval
объектное изменение.
Именование события в определении класса
Инициирование события путем вызова notify
Включение события свойства через SetObservable
атрибут
Создание прослушивателей для заданных классом событий и свойства PostSet
события
Определение функций обратного вызова прослушивателя, которые принимают дополнительные аргументы
Включение и отключение прослушивателей
fcneval
класс выполняет выражение MATLAB по заданной области двух переменных. 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 propertyEvent | Установка 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 предоставляют полный список методов, которые наследованы, когда вы разделяете на подклассы handle
класс.
Методы, наследованные от класса Handle | Цель |
---|---|
addlistener | Укажите прослушиватель для определенного события и присоедините прослушиватель объекта event-defining. |
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);
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
событие также обновляет поверхностные данные, все представления теперь синхронизируются
UpdateGraph
событие имеет место, когда представление MATLAB математической функции содержало в fcneval
объект изменяется. fcnview
объекты, которые содержат поверхностные графики, прислушиваются к этому событию, таким образом, они могут обновить графики, чтобы представлять новую функцию.
UpdateGraph
событие является заданным классом событием. fcneval
имена классов событие и вызовы notify
когда событие имеет место.
fcnview
класс задает прослушиватель для этого события. Когда fcneval
инициировал событие, fcnview
прослушиватель выполняет функцию обратного вызова, которая выполняет следовать действия:
Определяет если указатель объекта подложки, хранившего fcnview
объект все еще допустим (то есть, делает объект, все еще существуют),
Обновляет поверхностный XData
, YData
, и ZData
путем запроса fcneval
Data
объекта свойство.
fcneval
класс задает имя события в event
блок:
events UpdateGraph end
fcneval
класс задает метод набора свойств для FofXY
свойство. FofXY
свойство, которое хранит выражение MATLAB для математической функции. Это выражение должно быть допустимым выражением MATLAB для функции двух переменных.
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
set.FofXY
вызовы метода статический метод (fcneval.isSuitable
) определить пригодность заданного выражения. fcneval.isSuitable
возвращает MException
возразите, решает ли это, что выражение является неподходящим. fcneval.isSuitable
вызывает MException
конструктор непосредственно, чтобы создать более полезные сообщения об ошибке для пользователя.
set.FofXY
выпускает исключение с помощью MException.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
fcneval.isSuitable
метод мог обеспечить дополнительный тест, чтобы гарантировать, что выражение присвоило FofXY
свойство соответствует критериям, требуемым проектом класса.
Класс, возможно, реализовал событие набора свойств для FofXY
свойство и не должно было бы, поэтому, вызывать notify
(см., Прислушиваются к Изменениям в Значениях свойств). Определение события класса обеспечивает больше гибкости в этом случае, потому что можно лучше управлять инициированием события.
Например, предположите, что вы хотели обновить график, только если новые данные отличаются. Если новое выражение произвело те же данные в некотором допуске, set.FofXY
метод не мог инициировать событие и постараться не обновлять график. Однако метод мог все еще установить свойство на новое значение.
fcnview
класс создает прослушиватель для UpdateGraph
событие с помощью addlistener
метод:
obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',... @(src,evnt)listenUpdateGraph(obj,src,evnt)); % Add obj to argument list
fcnview
объектно-ориентированная память указатель на event.listener
объект в его HLUpdateGraph
свойство, которое используется, чтобы позволить/запретить прослушиватель контекстным меню (см., Включает и Отключает Прослушиватели).
fcnview
объект (obj
) добавляется к этим двум параметрам по умолчанию (src
, evnt
) переданный коллбэку прослушивателя. Следует иметь в виду, источник события (src
) fcneval
объект, но fcnview
объект содержит указатель объекта подложки, который обновляет коллбэк.
listenUpdateGraph
функция определяется следующим образом:
function listenUpdateGraph(obj,src,evnt) if ishandle(obj.HSurface) % If surface exists obj.updateSurfaceData % Update surface data end end
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
событие (См. События Набора свойств и Запроса для получения дополнительной информации о событиях свойства). Этот пример использует PostSet
событие для fcneval
Lm
свойство. Это свойство содержит двухэлементный вектор, указывающий диапазон, в котором выполнена математическая функция. Сразу после того, как это свойство изменяется (оператором как obj.Lm = [-3 5];
), fcnview
объекты, прислушивающиеся к этому событию, обновляют график, чтобы отразить новые данные.
Lm
Присвоение свойстваfcneval
класс задает функцию множества для Lm
свойство. Когда значение присвоено этому свойству во время объектной конструкции или переназначения свойства, следующая последовательность происходит:
Попытка предпринята, чтобы присвоить значение аргумента Lm
свойство.
set.Lm
метод выполняется, чтобы проверять, является ли значение в соответствующей области значений — если да, это делает присвоение, если не, это генерирует ошибку.
Если значение Lm
установлен успешно, MATLAB инициировал PostSet
событие.
Все прослушиватели выполняют свои коллбэки, но порядок недетерминирован.
PostSet
событие не имеет место, пока фактическое присвоение свойства не происходит. Функция набора свойств обеспечивает возможность иметь дело с потенциальными ошибками присвоения перед PostSet
событие имеет место.
Создать прослушиватель для PostSet
событие, необходимо установить SetObservable
свойства припишите
true
:
properties (SetObservable = true) Lm = [-2*pi 2*pi]; % specifies default value end
MATLAB автоматически инициировал событие, таким образом, не необходимо вызвать notify
.
Укажите, что Атрибуты свойств предоставляют список всех атрибутов свойства.
fcnview
класс создает прослушиватель для PostSet
событие с помощью addlistener
метод:
obj.HLLm = addlistener(obj.FcnObject,'Lm','PostSet',... @(src,evnt)listenLm(obj,src,evnt)); % Add obj to argument list
fcnview
объектно-ориентированная память указатель на event.listener
объект в его HLLm
свойство, которое используется, чтобы позволить/запретить прослушиватель контекстным меню (см., Включает и Отключает Прослушиватели).
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
возразите в качестве аргумента (в дополнение к необходимому источнику и аргументам данных о событиях), чтобы обеспечить доступ к указателю объектов прослушивателя.
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
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