Вызов метода

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

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

Похожие темы