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