Когда MATLAB® вызывает обычный метод, который имеет список аргументов, он использует следующие критерии, чтобы определить, какой метод вызывать
Класс крайнего левого аргумента, класс которого не задан как уступающий классу любого другого аргумента, выбирается в качестве доминирующего класса, и вызывается его метод.
Если этот класс не определяет вызываемый метод, вызывается функция с таким именем, которое находится в пути MATLAB.
Если такой функции не существует, MATLAB выдает ошибку, указывающую, что доминирующий класс не задает именованный метод.
MATLAB использует диспетчеризацию доминирующих аргументов, чтобы определить, какую версию метода вызывать. Во время диспетчеризации метода MATLAB определяет доминирующий класс из числа аргументов в вызове. В целом все классы MATLAB определены с помощью classdef
синтаксис имеет равный приоритет в целях диспетчеризации методов.
Классы, определенные с помощью classdef
синтаксис имеет приоритет над этими классами MATLAB:
double
, single
, int64
, uint64
, int32
, uint32
, int16
, uint16
, int8
, uint8
, char
, string
, logical
, cell
, struct
, и function_handle
.
В целом, когда два или более объектов являются частью списка аргументов, вызывается метод, заданный для класса самого левого объекта. Однако определяемые пользователем классы могут задавать относительное доминирование конкретных классов. Для получения дополнительной информации см. раздел Приоритет классов.
Например, предположим classA
определяет classB
как неполноценный и предположим, что оба класса определяют метод, называемый combine
.
Вызов метода с объектом classB
и classA
:
combine(B,A)
фактически вызывает combine
метод classA
потому что A
является доминирующим аргументом.
Классы MATLAB поддерживают как синтаксис функции, так и синтаксис записи через точку для методов вызова. Для примера, если setColor
является методом класса объекта X
, затем вызов setColor
с функцией обозначения будет:
X = setColor(X,'red');
Эквивалентный вызов метода с использованием записи через точку:
X = X.setColor('red')
Однако в некоторых случаях результаты для записи через точку могут отличаться в отношении того, как работает диспетчеризация MATLAB:
Если существует перегруженное subsref
, оно вызывается всякий раз, когда используется запись через точку. То есть оператор сначала проверяется, чтобы увидеть, является ли он подписанным назначением.
Если нет перегруженных subsref
, затем setColor
должен быть методом X
. Обычная функция или конструктор классов никогда не вызывается с помощью этого обозначения.
Только аргумент X
(слева от точки) используется для диспетчеризации. Никаких других аргументов, даже если они доминируют, не рассматривается. Поэтому запись через точку может вызывать только методы X
; методы других аргументов никогда не вызываются.
Случай, когда результат отличается. Вот пример случая, когда обозначения точек и функций могут дать различные результаты. Предположим, что у вас есть следующие классы:
classA
задает метод, называемый methodA
который требует объекта classB
как один из своих аргументов
classB
определяет classA
как уступающий classB
classdef (InferiorClasses = {?classA}) classB ... end
The methodA
метод задается двумя входными параметрами, один из которых является объектом classB
:
classdef classA methods function methodA(obj,obj_classB) ... end end
classB
не задает метод с таким же именем, как methodA
. Поэтому следующий синтаксис заставляет MATLAB искать путь для функции с таким же именем, как methodA
поскольку второй аргумент является объектом доминирующего класса. Если функция с таким именем существует в пути, MATLAB пытается вызвать эту функцию вместо метода classA
и, скорее всего, возвращает синтаксическую ошибку.
obj = classA(...); methodA(obj,obj_classB)
Запись через точку является более строгой в своем поведении. Для примера этот вызов на methodA
:
obj = classA(...); obj.methodA(obj_classB)
может вызывать только methodA
класса obj
.
Вы можете ссылаться на свойства или методы объекта, используя выражение в синтаксисе скобок:
obj.(expression)
Выражение должно вычисляться как char
вектор, являющийся именем свойства или метода. Для примера следующие операторы эквивалентны:
obj.Property1 obj.('Property1')
В этом случае obj
является объектом класса, который задает свойство, называемое Property1
. Поэтому можно пройти char
переменная в круглых скобках для ссылки на свойство:
propName = 'Property1'; obj.(propName)
Можно вызвать метод и передать входные параметры в метод с помощью другого набора круглых скобок:
obj.(expression)(arg1,arg2,...)
Используя это обозначение, можно сделать динамические ссылки на свойства и методы таким же образом, как можно создать динамические ссылки на поля structs
.
В качестве примера предположим, что у объекта есть методы, соответствующие каждому дню недели. Эти методы имеют те же имена, что и дни недели (Monday
, Tuesday
, и так далее). Кроме того, методы берут следующим char
векторные входные параметры, текущий день месяца (дата). Теперь предположим, что вы пишете функцию, в которой хотите вызвать правильный метод для текущего дня.
Используйте выражение, созданное с помощью date
и datestr
функции:
obj.(datestr(date,'dddd'))(datestr(date,'dd'))
Выражение datestr(date,'dddd')
возвращает текущий день как char
вектор. Для примера:
datestr(date,'dddd')
ans =
Tuesday
Выражение datestr(date,'dd')
возвращает текущую дату в виде char
вектор. Для примера:
datestr(date,'dd')
ans =
11
Поэтому выражение с использованием скобок (названное во вторник 11th) эквивалентно:
obj.Tuesday('11')
Для получения значения можно использовать индексацию точек в результат вызова метода. Для примера этот класс задает свойство и метод конструктора. Конструктор устанавливает значение свойства после оценки выражения с помощью входного параметра.
classdef polyEval properties Result end methods function obj = polyEval(x) if nargin obj.Result = 2*x.^3 + 7*x.^2 + 2*x + 7; end end end end
Можно индексировать в результат вызова метода конструктора для доступа к значению свойства. Для примера этот вызов на polyEval()
возвращает значение, назначенное свойству. Образец polyEval
класс создается как временная переменная и не сохраняется в рабочей области.
polyEval(-3.5).Result
ans = 0
В этом случае выражение, polyEval(-3.5).Result
представляет значение 0
(значение -3.5
является корнем полинома). Можно назначить результат оценки этого выражения переменной или использовать его в других выражениях.
Можно скинуть индекс в результат любого метода, который возвращает результат, для которого задана индексация точек, например, объект или структуру, которую можно индексировать с помощью свойства или имени поля. Необходимо включать круглые скобки во все выражения индексации, даже если аргументов нет. Например, чтобы индексировать в результат вызова на polyEval()
конструктор без входов, используйте это выражение.
polyEval().Result
Дополнительные сведения об индексации результатов вызовов функций см. в разделе Индексация результатов вызовов функций.
Могут быть ситуации, когда вы хотите создать методы для внутренних расчетов в классе, но не хотите публиковать эти методы как часть открытого интерфейса к классу. В этих случаях можно использовать Access
атрибут для установки доступа к одной из следующих опций:
public
- Любой код, имеющий доступ к объекту класса, может получить доступ к этому методу (по умолчанию).
private
- Ограничивает доступ метода к определяющему классу, исключая подклассы. Подклассы не наследуют частные методы.
protected
- ограничивает доступ метода к определяющему классу и подклассам, выведенным из определяющего класса. Подклассы наследуют этот метод.
Список доступа - ограничивает доступ метода к классам в списке доступа. Для получения дополнительной информации см. Раздел «Доступ для членов класса»
Локальные и вложенные функции внутри файлов методов имеют тот же доступ что и метод. Локальные функции внутри файла определения класса имеют частный доступ к классу, заданному в том же файле.
Подкласс может переопределить реализацию метода, заданного в суперклассе. Если подклассу необходимо выполнить дополнительный код вместо полной замены суперкласса. Классы MATLAB могут использовать специальный синтаксис для вызова методов суперкласса из реализации подкласса для одноименного метода.
Синтаксис для вызова метода суперкласса в классе подкласса использует символ @:
MethodName@SuperclassName
Для примера выполните следующее disp
метод задан для Stock
класс, который получают из Asset
класс. Метод сначала вызывает Asset
классы disp
метод, прохождение Stock
объект так, что Asset
компоненты Stock
можно отобразить объект. После Asset
disp
метод возвращает, Stock
disp
метод отображает два Stock
свойства:
classdef Stock < Asset methods function disp(s) disp@Asset(s) % Call base class disp method first fprintf(1,'Number of shares: %g\nShare price: %3.2f\n',... s.NumShares,s.SharePrice); end % disp end end
Следующие ограничения применяются к вызовам методов суперкласса. Вы можете использовать это обозначение только в:
Метод, имя которого совпадает с именем метода суперкласса, который вы вызываете
Класс, который является подклассом суперкласса, метод которого вы вызываете
MATLAB builtin
функция позволяет вам вызвать встроенную версию функции, которая была перегружена методом.