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