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

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

Этот пример задает класс, который изменяет поведение индексации значения по умолчанию путем реализации subsref и subsasgn методы. Класс также реализует преобразование типов и сложение путем реализации a double метод конвертера и a 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);
         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. Путем реализации double метод конвертера, возможно добавить MyDataClass возразите против другого класса объекта. Однако другой класс должен реализовать double метод, который также возвращает массив типа 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);
               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

Похожие темы