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

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

Классы 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 методы могут должны быть закодировать каждое определенное свойство и имя метода явным образом, чтобы не нарушать проект класса.

Похожие темы