Когда 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
Метод 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
, текущий день месяца (дата). Теперь предположите, что вы пишете функцию, в которой вы хотите вызвать правильный метод в течение текущего дня.
Используйте выражение, созданное с функциями datestr
и date
:
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
Поэтому выражение с помощью точечных круглых скобок (обратился к вторнику 11-е) является эквивалентом:
obj.Tuesday('11')
Могут быть ситуации, где вы хотите создать методы для внутреннего вычисления в классе, но не хотите публиковать эти методы как часть открытого интерфейса к классу. В этих случаях можно использовать атрибут Access
, чтобы установить доступ к одной из следующих опций:
public
— Любой код, имеющий доступ к объекту класса, может получить доступ к этому методу (значение по умолчанию).
private
— Ограничивает доступ к методу к классу определения, исключая подклассы. Подклассы не наследовали закрытые методы.
protected
— Ограничивает доступ к методу к классу определения и разделяет на подклассы выведенный от класса определения. Подклассы наследовали этот метод.
Список доступа — Ограничивает доступ к методу к классам в списке доступа. Для получения дополнительной информации см. Доступ для членов класса
Локальные и вложенные функции в файлах метода имеют тот же доступ как метод. Локальные функции в файле определения класса имеют частный доступ к классу, заданному в том же файле.
Подкласс может заменить реализацию метода, заданного в суперклассе. Если метод подклассов должен выполнить дополнительный код вместо завершенной замены метода суперкласса. Классы MATLAB могут использовать специальный синтаксис для вызова методов суперкласса от реализации подкласса для одноименного метода.
Синтаксис, чтобы вызвать метод суперкласса в классе подкласса использует символ:
MethodName@SuperclassName
Например, следующий метод disp
задан для класса Stock
, который выведен от класса Asset
. Метод сначала вызывает класс Asset
метод disp
, передавая объект Stock
так, чтобы компоненты Asset
объекта Stock
могли быть отображены. После того, как метод disp
Asset
возвращается, метод disp
Stock
отображает два свойства 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
Следующие ограничения применяются к вызову методов суперкласса. Можно использовать это обозначение только в:
Метод, имеющий то же имя как метод суперкласса, вы вызываете
Класс, который является подклассом суперкласса, метод которого вы вызываете
Функция builtin
MATLAB позволяет вам вызвать встроенную версию функции, которая была перегружена методом.