Когда 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 векторные входные аргументы, текущий день месяца (дата). Теперь предположим, что вы пишете функцию, в которой вы хотите вызвать правильный метод для текущего дня.
Использовать выражение, созданное с помощью 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Поэтому выражение, использующее точечные скобки (называемое во вторник 11-м), эквивалентно:
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 функция позволяет вызвать встроенную версию функции, которая была перегружена методом.