Вызов метода

Определение, какой метод вызывается

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

Похожие темы