Класс с измененной индексацией

Как изменить индексацию класса

Этот пример задает класс, который изменяет поведение индексации значения по умолчанию путем реализации subsref и subsasgn методы. Класс также реализует преобразование типов и сложение путем реализации double метод конвертера и plus метод.

Цель проекта класса к:

  • Позвольте вам обработать объект класса как числовой массив

  • Смогите содержать нечисловые и числовые данные в объекте класса

Описание класса

Класс имеет три свойства:

  • Data — числовые тестовые данные

  • Description — описание тестовых данных

  • Date — тест даты проводился

Примите, что у вас есть следующие случайные данные (randi):

d = randi(9,3,4)
d =

     8     9     3     9
     9     6     5     2
     2     1     9     9

Создайте экземпляр класса:

obj = MyDataClass(d,'Test001')
obj = 

  MyDataClass with properties:

           Data: [3x4 double]
    Description: 'Test001'
           Date: [2012 1 7 9 32 34.5190]

Аргументы конструктора передают значения для Data и Description свойства. clock функционируйте присваивает значение Date свойство из конструктора. Этот подход получает информацию о времени и дате, когда каждый экземпляр создается.

Вот предварительный листинг кода без subsrefsubsasgn double, и plus методы.

classdef MyDataClass
   properties
      Data
      Description
   end
   properties (SetAccess = private)
      Date
   end
   methods
      function obj = MyDataClass(data,desc)
         if nargin > 0
            obj.Data = data;
         end
         if nargin > 1
            obj.Description = desc;
         end
         obj.Date = clock;
      end
   end
end

Специализация Преобразованной в нижний индекс Ссылки - subsref

Реализуйте subsref метод, чтобы поддержать и значение по умолчанию и специализированный тип индексации.

  • Значение по умолчанию индексированное ссылочное поведение для скалярных объектов:

    obj.Data(2,3)
    ans =
    
         5
  • И добавить функциональность, чтобы индексировать в Data свойство с выражением как этот оператор:

    obj(2,3)
    

Если вы переопределяете '()' индексация к доступу к поддержке к Data свойство, вы не можете создать массивы MyDataClass объекты и использование '()' индексация, чтобы получить доступ к отдельным объектам. Можно сослаться только на скалярные объекты.

Достигнуть целей проекта, subsref метод должен обработать все типы индексации. subsref метод:

  • Вызывает builtin subsref функция для '.' индексация

  • Возвращает ошибку для '{}' индексация

  • Задает его собственную версию '()' индексация.

Результат: obj(i) эквивалентно obj.Data(i).

function sref = subsref(obj,s)
   % obj(i) is equivalent to obj.Data(i)
   switch s(1).type
      case '.'
         sref = builtin('subsref',obj,s);
      case '()'
         if length(s) < 2
            sref = builtin('subsref',obj.Data,s);
            return
         else
            sref = builtin('subsref',obj,s);
         end
      case '{}'
         error('MYDataClass:subsref',...
            'Not a supported subscripted reference')
   end
end

Специализация Преобразованного в нижний индекс Присвоения - subsasgn

Чтобы поддержать эквивалент индексируемого ссылочного поведения с индексируемым присвоением, реализуйте subsasgn метод.

  • Поддержите индексированное присвоение значения по умолчанию:

    obj.Data(2,3) = 9;
  • Добавьте функциональность, чтобы присвоить значения Data свойство с выражением как этот оператор:

    obj(2,3) = 9;

Как subsref метод, subsasgn метод:

  • Вызывает builtin subsasgn функция для '.' индексация

  • Возвращает ошибку для '{}' индексация

  • Задает его собственную версию '()' индексация.

substruct функция переопределяет тип индекса, и индекс преобразовывает в нижний индекс структуру, которую MATLAB® передает subsref и subsasgn.

function obj = subsasgn(obj,s,val)
   if isempty(s) && isa(val,'MyDataClass')
      obj = MyDataClass(val.Data,val.Description);
   end
   switch s(1).type
      case '.'
         obj = builtin('subsasgn',obj,s,val);
      case '()'
         if length(s)<2
            if isa(val,'MyDataClass')
               error('MyDataClass:subsasgn',...
                  'Object must be scalar')
            elseif isa(val,'double')
               % Redefine the struct s to make the call: obj.Data(i)
               snew = substruct('.','Data','()',s(1).subs(:));
               obj = subsasgn(obj,snew,val);
            end
         end
      case '{}'
         error('MyDataClass:subsasgn',...
            'Not a supported subscripted assignment')
   end
end

Реализация Сложения для Данных объектов - дважды и плюс

Во-первых, реализуйте double метод, который преобразует объект в массив, удваивается. Путем реализации double метод конвертера, возможно добавить MyDataClass возразите против другого класса объекта. Однако другой класс должен реализовать double метод, который также возвращает массив, удваивается. Для получения дополнительной информации о преобразовании типов см. Преобразователи объектов.

Позвольте прямое сложение Data значения свойств путем реализации plus метод. Реализация plus метод включает использование + оператор для сложения MyDataClass объекты.

Поскольку плюс метод реализует сложение путем добавления двойных массивов, MATLAB:

  • Примените правила сложения при добавлении MyDataClass объекты

  • Возвращает ошибки для любого условия, которое может вызвать ошибки в числовом сложении по умолчанию. Например, несоответствие размерности.

plus метод использует double метод, чтобы преобразовать объект в числовые значения прежде, чем выполнить сложение:

function a = double(obj)
   a = obj.Data;
end
function c = plus(obj,b)
   c = double(obj) + double(b);
end

Например, plus метод позволяет вам добавить скалярный номер в объект Data массив.

Вот значения Data, отображенное использование индексированная ссылка:

obj(:,:)
ans =

     8     9     3     9
     9     6     9     2
     2     1     9     9

Добавьте 7 к массиву, содержавшемуся в Data свойство:

obj + 7
ans =

    15    16    10    16
    16    13    16     9
     9     8    16    16

MyDataClass.m

Это определение для MyDataClass включает end метод индексирования обсужден в конце как Индекс объекта.

classdef MyDataClass
   % Example for "A Class with Modified Indexing"
   properties
      Data
      Description
   end
   properties (SetAccess = private)
      Date
   end
   methods
      function obj = MyDataClass(data,desc)
         % Support 0-2 args
         if nargin > 0
            obj.Data = data;
         end
         if nargin > 1
            obj.Description = desc;
         end
         obj.Date = clock;
      end
      
      function sref = subsref(obj,s)
         % obj(i) is equivalent to obj.Data(i)
         switch s(1).type
            case '.'
               sref = builtin('subsref',obj,s);
            case '()'
               if length(s)<2
                  sref = builtin('subsref',obj.Data,s);
                  return
               else
                  sref = builtin('subsref',obj,s);
               end
            case '{}'
               error('MyDataClass:subsref',...
                  'Not a supported subscripted reference')
         end
      end
      
      function obj = subsasgn(obj,s,val)
         if isempty(s) && isa(val,'MyDataClass')
            obj = MyDataClass(val.Data,val.Description);
         end
         switch s(1).type
            case '.'
               obj = builtin('subsasgn',obj,s,val);
            case '()'
               %
               if length(s)<2
                  if isa(val,'MyDataClass')
                     error('MyDataClass:subsasgn',...
                        'Object must be scalar')
                  elseif isa(val,'double')
                     snew = substruct('.','Data','()',s(1).subs(:));
                     obj = subsasgn(obj,snew,val);
                  end
               end
            case '{}'
               error('MyDataClass:subsasgn',...
                  'Not a supported subscripted assignment')
         end
      end
      
      function a = double(obj)
         a = obj.Data;
      end
      
      function c = plus(obj,b)
         c = double(obj) + double(b);
      end
      
      function ind = end(obj,k,n)
         szd = size(obj.Data);
         if k < n
            ind = szd(k);
         else
            ind = prod(szd(k:end));
         end
      end
   end
end

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте