Индексация объектного массива

Индексируемая ссылка по умолчанию и присвоение

Классы MATLAB® поддерживают объектный массив, индексирующий по умолчанию. Много проектов класса не требуют никакой модификации к этому поведению.

Массивы позволяют вам сослаться и присвоить элементы массива с помощью преобразованного в нижний индекс обозначения. Это обозначение задает индексы определенных элементов массива. Например, предположите, что вы создаете два массива чисел (использующий randi и конкатенацию).

Создайте массив 3 на 4 целых чисел от 1 до 9:

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

     4     8     5     7
     4     2     6     3
     7     5     7     7

Создайте 1 3 массив чисел 3, 6, 9:

B = [3 6 9];

Ссылка и элементы присвоения любого массива с помощью индексных значений в круглых скобках:

B(2) = A(3,4);
B
B =
     3     7     9

Когда вы выполняете оператор, который включает индексируемую ссылку:

C = A(3,4);

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

C(4) = 7;

MATLAB вызывает встроенную функцию subsasgn, чтобы определить, как интерпретировать оператор.

Значение по умолчанию MATLAB subsref и функции subsasgn также работает с пользовательскими объектами. Например, создайте массив объектов того же класса:

for k=1:3
   objArray(k) = MyClass;
end

Ссылание на второй элемент в объектном массиве, objArray, возвращает объект, созданный когда k = 2:

D = objArray(2);
class(D)
ans =

MyClass

Можно присвоить объект массиву объектов того же класса или неинициализированную переменную:

newArray(3,4) = D;

Массивы объектов ведут себя во многом как числовые массивы в MATLAB. Вы не должны реализовывать специальные методы предоставить стандартному поведению массивов ваш класс.

Для получения общей информации об индексации массива, смотрите Индексацию массива.

Что можно изменить

Можно изменить класс индексированная ссылка и/или поведение присвоения методами класса с реализацией под названием subsref и subsasgn. Для описания синтаксиса смотрите их соответствующие страницы с описанием.

Если вы добавляете subsref или метод subsasgn к вашему классу, затем MATLAB вызывает только метод класса, не встроенную функцию. Поэтому ваш метод класса должен реализовать всю индексируемую ссылку и операции присвоения, которые вы хотите, чтобы ваш класс поддержал. Эти операции включают:

  • Запись через точку вызывает к методам класса

  • Ссылка записи через точку и присвоение включающие свойства

  • Любая индексация с помощью круглых скобок '()'

  • Любая индексация с помощью фигурных скобок '{}'

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

Когда изменить поведение индексации

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

Этот оператор:

obj.Data(2,3)

Возвращает значение, содержавшееся во второй строке, третьем столбце массива. Если у вас есть массив объектов, используйте выражение как:

objArray(3).Data(2,3)

Этот оператор возвращает значение, содержавшееся во второй строке, третьем столбце третьего элемента в массиве.

Измените поведение индексации значения по умолчанию, когда ваш проект класса требует поведения, которое отличается от поведения значения по умолчанию MATLAB.

Встроенный subsref и subsasgn Называются в Методах

MATLAB не вызывает заданный классом subsref или методы subsasgn в перегруженных методах. В методах класса MATLAB всегда вызывает встроенный subsref и функции subsasgn. Это поведение происходит в заданном классом subsref и методах subsasgn также.

Например, в методе класса, этой точечной ссылке:

obj.Prop

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

subsref(obj,substruct('.','Prop'))

Каждый раз, когда метод требует функциональности заданного классом subsref или метода subsasgn, класс должен вызвать перегруженные методы как функции. Не используйте операторы, '()', '{}' или '.'.

Например, предположите, что вы задаете класс, чтобы представлять полином. Этот класс имеет метод subsref, который оценивает полином со значением независимой переменной, равной индексу. Примите, что этот оператор задает полином со своими коэффициентами:

p = polynom([1 0 -2 -5]);

Выражение MATLAB для получившегося полинома:

x^3 - 2*x - 5

Это преобразованное в нижний индекс выражение возвращает значение полинома в x = 3:

p(3)
ans =
    16

Предположим, что вы хотите использовать эту функцию в другом методе класса. Для этого вызовите функцию subsref непосредственно. Метод evalEqual принимает два объекта polynom и значение, в котором можно оценить полиномы:

methods
   function ToF = evalEqual(p1,p2,x)
      % Create arguments for subsref
      subs.type = '()';
      subs.subs = {x};
      % Need to call subsref explicitly 
      y1 = subsref(p1,subs);
      y2 = subsref(p2,subs);
      if y1 == y2
         ToF = true;
      else 
         ToF = false;
      end
   end
end

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

Предотвращение переопределяющего доступа к атрибутам

Поскольку subsref является методом класса, он имеет доступ к частным членам класса. Постарайтесь не непреднамеренно предоставлять доступ к закрытым методам и свойствам, когда вы обрабатываете различные типы ссылки. Считайте этот метод subsref заданным для класса, имеющего частные свойства, x и y:

classdef MyPlot
   properties (Access = private)
      x
      y
   end
   properties
      Maximum
      Minimum
      Average
   end
   methods
      function obj = MyPlot(x,y)
         obj.x = x;
         obj.y = y;
         obj.Maximum = max(y);
         obj.Minimum = min(y);
         obj.Average = mean(y);
      end
      function B = subsref(A,S)
         switch S(1).type
            case '.'
               switch S(1).subs
                  case 'plot'
                     % Reference to A.x and A.y call built-in subsref
                     B = plot(A.x,A.y);
                  otherwise
                     % Enable dot notation for all properties and methods
                     B = A.(S.subs);
               end
         end
      end
   end
end

Этот subsref позволяет использованию записи через точку создать график с помощью имени 'plot'. Оператор:

obj = MyPlot(1:10,1:10);
h = obj.plot;

вызывает функцию plot и возвращает указатель на графический объект.

Вы не должны кодировать каждый метод и имя свойства. Код otherwise во внутреннем блоке switch управляет любой ссылкой имени, которую вы явным образом не задаете в операторах case. Однако использование этого метода представляет любых членов частного и защищенного класса через запись через точку. Например, можно сослаться на частную собственность, x, с этим оператором:

obj.x
ans =

     1     2     3     4     5     6     7     8     9    10

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

Похожие темы