Свойства и методы, заданные классом, образуют интерфейс, который определяет, как пользователи классов взаимодействуют с объектами класса. При создании группы связанных классов интерфейсы определяют общий интерфейс для всех этих классов. Фактические реализации интерфейса могут отличаться от одного класса к другому.
Рассмотрим набор классов, предназначенных для представления различных типов графиков. Все классы должны реализовать Data свойство, содержащее данные, используемые для генерации графика. Однако форма данных может значительно отличаться от одного типа графика к другому. Каждый класс может реализовать Data свойство по-разному.
Те же различия применяются и к методам. Все классы могут иметь draw метод, который создает график, но реализация этого метода изменяется с типом графика.
Основная идея класса интерфейса состоит в том, чтобы задать свойства и методы, которые каждый подкласс должен реализовать, не определяя фактическую реализацию. Этот подход позволяет применить последовательный интерфейс к группе связанных объектов. Когда вы добавляете больше классов в будущем, интерфейс остается неизменным.
Этот пример создает интерфейс для классов, используемых для представления специализированных графиков. Интерфейс является абстрактным классом, который задает свойства и методы, которые должны реализовать подклассы, но не задает, как реализовать эти компоненты.
Этот подход обеспечивает применение последовательного интерфейса, обеспечивая при этом необходимую гибкость для реализации внутренней работы каждого специализированного подкласса по-разному.
В этом примере папка пакета содержит интерфейс, производные подклассы и служебную функцию:
+graphics/GraphInterface.m % abstract interface class +graphics/LineGraph.m % concrete subclass
The graph класс задает следующие свойства, которые должны задавать подклассы:
Primitive - Указатель на графический объект, используемый для реализации специализированного графика. Пользователь класса не должен непосредственно обращаться к этим объектам, поэтому это свойство имеет protected
SetAccess и GetAccess.
AxesHandle - Указатель на оси, используемые для графика. Специализированные graph объекты могут задать свойства объекта осей. Это свойство имеет protected
SetAccess и GetAccess.
Data - Все подклассы GraphInterface класс должен хранить данные. Тип данных изменяется, и каждый подкласс определяет механизм хранения. Пользователи подкласса могут изменять значения данных таким образом, чтобы это свойство имело права общедоступного доступа.
The GraphInterface именует три абстрактных метода, которые должны реализовывать подклассы. The GraphInterface класс также предлагает в комментариях, что каждый конструктор подкласса должен принимать пары графика data и имя свойства/property значение для всех свойств класса.
Конструктор подкласса - Принимает пары данных и P/V и возвращает объект.
draw - Используется для создания примитива чертежа и визуализации графика данных в соответствии с типом графика, реализованного подклассом.
zoom - Реализация метода масштабирования путем изменения осей CameraViewAngle свойство. Интерфейс предполагает использование camzoom функция для консистентности среди подклассов. Кнопки масштаба, созданные addButtons статический метод использует этот метод в качестве коллбэка.
updateGraph - Метод, вызываемый set.Data метод для обновления нанесенных на график данных каждый раз, когда Data изменения свойств.
Пакет классов, которые получают из GraphInterface абстрактный класс реализует следующее поведение:
Создание образца специализированного GraphInterface объект (объект подкласса) без визуализации графика
Установка какого-либо свойства объекта или его отсутствия при создании специализированного GraphInterface объект
Изменение любого свойства объекта автоматически обновляет текущий отображаемый график
Разрешение каждой специализированной GraphInterface объект для реализации любых дополнительных свойств, требуемых для предоставления пользователям классов контроля над этими характеристиками.
The GraphInterface класс является абстрактным классом, который задает методы и свойства, используемые подклассами. Комментарии в абстрактном классе описывают предполагаемую реализацию:
classdef GraphInterface < 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 AxesHandle end properties Data end methods (Abstract) draw(obj) % Use a line, surface, % or patch graphics primitive zoom(obj,factor) % Change the CameraViewAngle % for 2D and 3D views % use camzoom for consistency updateGraph(obj) % Update the Data property and % update the drawing primitive end methods function set.Data(obj,newdata) obj.Data = newdata; updateGraph(obj) end function addButtons(gobj) hfig = get(gobj.AxesHandle,'Parent'); uicontrol(hfig,'Style','pushbutton','String','Zoom Out',... 'Callback',@(src,evnt)zoom(gobj,.5)); uicontrol(hfig,'Style','pushbutton','String','Zoom In',... 'Callback',@(src,evnt)zoom(gobj,2),... 'Position',[100 20 60 20]); end end end
The GraphInterface класс реализует метод набора свойств (set.Data) для мониторинга изменений в Data свойство. Альтернативой является определение Data свойство как Abstract и разрешить подклассам определять, реализовывать ли метод доступа к набору для этого свойства. The GraphInterface класс задает метод доступа к набору, который вызывает абстрактный метод (updateGraph, который должен реализовать каждый подкласс). The GraphInterface интерфейс накладывает определенный проект на весь пакет классов, не ограничивая гибкость.
The addButtons метод добавляет кнопки для zoom методы, которые должен реализовать каждый подкласс. Использование метода вместо обычной функции позволяет addButtons для доступа к защищенным данным класса (указатель на оси). Используйте объект zoom метод как кнопочный коллбэк.
function addButtons(gobj) hfig = get(gobj.AxesHandle,'Parent'); uicontrol(hfig,'Style','pushbutton',... 'String','Zoom Out',... 'Callback',@(src,evnt)zoom(gobj,.5)); uicontrol(hfig,'Style','pushbutton',... 'String','Zoom In',... 'Callback',@(src,evnt)zoom(gobj,2),... 'Position',[100 20 60 20]); end
Этот пример задает только один подкласс, используемый для представления простого линейного графика. Это происходит от GraphInterface, но предоставляет реализации для абстрактных методов draw, zoom, updateGraph, и его собственный конструктор. Базовый класс GraphInterface и подкласс все содержатся в пакете (graphics), который необходимо использовать для ссылки на имя класса:
classdef LineGraph < graphics.GraphInterfaceThe LineGraph класс реализует интерфейс, заданный в GraphInterface Класс и добавляет два дополнительных свойства - LineColor и LineType. Этот класс определяет начальные значения для каждого свойства, поэтому установка значений свойств в конструкторе является необязательной. Можно создать LineGraph объект без данных, но вы не можете создать графиков из этого объекта.
properties LineColor = [0 0 0]; LineType = '-'; end
Конструктор принимает struct с x и y координатные данные и пары имя/значение свойства:
function gobj = LineGraph(data,varargin) if nargin > 0 gobj.Data = data; if nargin > 2 for k=1:2:length(varargin) gobj.(varargin{k}) = varargin{k+1}; end end end end
The LineGraph
draw метод использует значения свойств, чтобы создать line объект. The LineGraph класс хранит line указатель как защищенные данные класса. Чтобы поддержать использование никаких входных параметров для конструктора классов, draw проверяет Data свойство для определения, пуст ли он перед продолжением:
function gobj = draw(gobj) if isempty(gobj.Data) error('The LineGraph object contains no data') end h = line(gobj.Data.x,gobj.Data.y,... 'Color',gobj.LineColor,... 'LineStyle',gobj.LineType); gobj.Primitive = h; gobj.AxesHandle = get(h,'Parent'); end
The LineGraph
zoom метод следует комментариям в GraphInterface класс, который предлагает использовать camzoom функция. camzoom обеспечивает удобный интерфейс для масштабирования и правильно работает с кнопками, созданными addButtons способ.
Методы набора свойств обеспечивают удобный способ автоматического выполнения кода, когда значение свойства изменяется впервые в конструкторе. (См. «Методы набора свойств».) The linegraph класс использует методы set, чтобы обновить line примитивные данные (которые вызывают перерисовку графика) всякий раз, когда изменяется значение свойства. Использование методов набора свойств предоставляет способ быстро обновить график данных, не требуя вызова draw способ. The draw метод обновляет график путем сброса всех значений, чтобы соответствовать текущим значениям свойств.
Три свойства используют методы набора: LineColor, LineType, и Data. LineColor и LineType свойства, добавленные LineGraph Классы и специфичны для line примитив, используемый этим классом. Другие подклассы могут задать различные свойства, уникальные для их специализации (для примера FaceColor).
The GraphInterface класс реализует Data метод набора свойств. Однако GraphInterface класс требует, чтобы каждый подкласс определял метод, называемый updateGraph, который обрабатывает обновление данных графика для конкретного используемого примитива чертежа.
Вот LineGraph определение класса.
classdef LineGraph < graphics.GraphInterface properties LineColor = [0 0 0] LineType = '-' end methods function gobj = LineGraph(data,varargin) if nargin > 0 gobj.Data = data; if nargin > 1 for k=1:2:length(varargin) gobj.(varargin{k}) = varargin{k+1}; end end end end function gobj = draw(gobj) if isempty(gobj.Data) error('The LineGraph object contains no data') end h = line(gobj.Data.x,gobj.Data.y,... 'Color',gobj.LineColor,... 'LineStyle',gobj.LineType); gobj.Primitive = h; gobj.AxesHandle = h.Parent; end function zoom(gobj,factor) camzoom(gobj.AxesHandle,factor) end function updateGraph(gobj) set(gobj.Primitive,... 'XData',gobj.Data.x,... 'YData',gobj.Data.y) end function set.LineColor(gobj,color) gobj.LineColor = color; set(gobj.Primitive,'Color',color) end function set.LineType(gobj,ls) gobj.LineType = ls; set(gobj.Primitive,'LineStyle',ls) end end end
LineGraph КлассThe LineGraph класс задает простой API, заданный как graph базовый класс и реализует свой специализированный тип графика:
d.x = 1:10; d.y = rand(10,1); lg = graphics.LineGraph(d,'LineColor','b','LineType',':'); lg.draw; lg.addButtons;
Нажатие кнопки Zoom In показывает zoom способ обеспечения коллбэка для кнопки.

Изменение свойств обновляет график:
d.y = rand(10,1); lg.Data = d; lg.LineColor = [0.9,0.1,0.6];
Теперь нажмите Zoom Out и посмотрите новые результаты:
