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.
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 функция непосредственно. The 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 и возвращает указатель в графический объект.
Вам не нужно кодировать каждый метод и имя свойства. The otherwise код во внутреннем switch блок управляет любой ссылкой на имя, в которой вы явным образом не заданы case операторы. Однако использование этого метода предоставляет любые частные и защищенные члены класса через запись через точку. Для примера можно ссылаться на частную собственность, x, с этим оператором:
obj.x
ans =
1 2 3 4 5 6 7 8 9 10Этот же вопрос касается написания subsasgn метод, который позволяет назначать частным или защищенным свойствам. Ваши subsref и subsasgn методы могут потребовать явного кодирования каждого конкретного свойства и имени метода, чтобы избежать нарушений проекта класса.