Определение интерфейсного суперкласса

Интерфейсы

Свойства и методы, заданные классом, формируют интерфейс, который определяет, как пользователи класса взаимодействуют с объектами класса. При создании группы связанных классов интерфейсы задают общий интерфейс ко всем этим классам. Фактическая реализация интерфейса может отличаться от одного класса до другого.

Считайте набор классов спроектированным, чтобы представлять различные типы графиков. Все классы должны реализовать Data свойство содержать данные раньше генерировало график. Однако форма данных может значительно отличаться от одного типа графика другому. Каждый класс может реализовать Data свойство по-другому.

Те же различия применяются к методам. Все классы могут иметь draw метод, который создает график, но реализацию этого метода изменения с типом графика.

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

Интерфейсные графики реализации класса

Этот пример создает интерфейс для классов, используемых, чтобы представлять специализированные графики. Интерфейс является абстрактным классом, который задает свойства и методы, которые подклассы должны реализовать, но не задают, как реализовать эти компоненты.

Этот подход осуществляет использование сопоставимого интерфейса при обеспечении необходимой гибкости, чтобы реализовать внутренние работы каждого специализированного подкласса по-другому.

В этом примере папка пакета содержит интерфейс, выведенные подклассы и служебную функцию:

+graphics/GraphInterface.m % abstract interface class
+graphics/LineGraph.m      % concrete subclass

Interface Properties и методы

graph класс задает следующие свойства, которые должны задать подклассы:

  • Primitive — Указатель графического объекта раньше реализовывал специализированный график. У пользователя класса нет потребности получить доступ к этим объектам непосредственно, таким образом, это свойство имеет protected SetAccess и GetAccess.

  • AxesHandle — Указатель осей используется для графика. Специализированный graph объекты могут установить свойства объекта осей. Это свойство имеет protected SetAccess и GetAccess.

  • Data — Все подклассы GraphInterface класс должен хранить данные. Тип данных варьируется, и каждый подкласс задает механизм хранения. Пользователи подкласса могут изменить значения данных, таким образом, это свойство имеет права открытого доступа.

GraphInterface имена классов три абстрактных метода, которые должны реализовать подклассы. GraphInterface класс также предлагает в комментариях, что каждый конструктор подкласса должен принять данные о графике и имя свойства / пары значения свойства для всех свойств класса.

  • Конструктор подкласса — Принимает данные и пары P/V и возвращает объект.

  • draw — Используемый, чтобы создать примитивный рисунок и представить график данных согласно типу графика, реализованного подклассом.

  • zoom — Реализация метода изменения масштаба путем изменения осей CameraViewAngle свойство. Интерфейс предлагает использование camzoom функция для непротиворечивости среди подклассов. Кнопки изменения масштаба создаются addButtons использование статического метода этот метод как коллбэк.

  • updateGraph — Метод вызван set.Data метод, чтобы обновить отображенные на графике данные каждый раз, когда Data изменения свойства.

Интерфейс ведет дизайн класса

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

  • Создание экземпляра специализированного GraphInterface объект (разделяют объект на подклассы), не представляя график

  • Определение любого или ни одних из свойств объектов, когда вы создаете специализированный GraphInterface объект

  • Изменение любого свойства объекта автоматически обновляет в настоящее время отображенный график

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

Определение интерфейса

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 

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

Метод, чтобы работать со всеми подклассами

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

Получение реального класса - LineGraph

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

classdef LineGraph < graphics.GraphInterface

Добавление свойств

LineGraph класс реализует интерфейс, заданный в GraphInterface класс и добавляет два дополнительных свойства — LineColor и LineType. Этот класс задает начальные значения для каждого свойства, так определение, что значения свойств в конструкторе являются дополнительными. Можно создать LineGraph объект без данных, но вы не можете произвести график из того объекта.

properties
   LineColor = [0 0 0];
   LineType = '-';
end

Конструктор LineGraph

Конструктор принимает 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

Реализация Метода ничьей

LineGraph draw метод использует значения свойств, чтобы создать a line объект. 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

Реализация Метода изменения масштаба

LineGraph zoom метод следует комментариям в GraphInterface класс, которые предлагают использовать camzoom функция. camzoom обеспечивает удобный интерфейс к изменению масштаба и действует правильно с кнопками, созданными addButtons метод.

Определение методов набора свойств

Методы набора свойств обеспечивают удобный способ выполнить код автоматически, когда значение свойства изменяется впервые в конструкторе. (См. Методы Набора свойств.) linegraph класс использует методы установки обновить line примитивные данные (который вызывает перерисовку графика) каждый раз, когда значение свойства изменяется. Использование методов набора свойств обеспечивает способ обновить график данных быстро, не требуя вызова draw метод. draw метод обновляет график путем сброса всех значений, чтобы совпадать с текущими значениями свойств.

Три свойства используют методы установки: LineColor, LineType, и Data'LineColor' и LineType свойства, добавленные LineGraph класс и характерен для line примитивный используемый этим классом. Другие подклассы могут задать различные свойства, уникальные для их специализации (например, FaceColor).

GraphInterface класс реализует Data метод набора свойств. Однако GraphInterface класс требует, чтобы каждый подкласс задал метод под названием updateGraph, который обрабатывает обновление, отображают данные на графике для определенного рисунка, примитивного используемый.

Класс LineGraph

Вот 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 Класс

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 и смотрите новые результаты:

Похожие темы