Существует несколько функций MATLAB ®, создающих массивы определенного размера и типа, например: ones и zeros. Определяемые пользователем классы могут добавлять поддержку функций создания массивов, не требуя использования перегруженного синтаксиса метода.
Поддержка класса для любой из функций создания массива позволяет разрабатывать код, который можно совместно использовать со встроенными и пользовательскими типами данных. Например, класс переменной x в следующем коде может быть встроенным типом во время начальной разработки, а затем быть заменен определяемым пользователем классом, который прозрачно перегружает zeros:
cls = class(x); zArray = zeros(m,n,cls);
Функции создания массивов создают массивы определенного типа двумя способами:
Синтаксис имени класса - указывает имя класса, определяющее тип элементов массива.
Синтаксис объекта Prototype - предоставляет объект Prototype, используемый функцией для определения типа и других характеристик элементов массива.
Например:
zArray = zeros(2,3,'uint8');
p = uint8([1 3 5 ; 2 4 6]);
zArray = zeros(2,3,'like',p);
После добавления поддержки этих функций в класс с именем MyClass, можно использовать подобный синтаксис с этим классом:
zArray = zeros(2,3,'MyClass');Или передайте объект вашего класса:
p = MyClass(...);
zArray = zeros(size(p),'like',p);
MATLAB использует эти аргументы для отправки соответствующему методу в классе.
Следующие функции поддерживают этот вид перегрузки.
Чтобы создать массив объектов по умолчанию, которые не требуют входных аргументов для конструктора, используйте синтаксис имени класса.
Чтобы создать массив объектов с определенными значениями свойств или если конструктору требуются другие входные данные, используйте объект prototype для предоставления этой информации.
Классы могут поддерживать как имя класса, так и синтаксис объекта прототипа.
Синтаксис имени класса можно реализовать с помощью true и false хотя эти функции не поддерживают этот синтаксис по умолчанию.
Если класс реализует синтаксис имени класса, но не реализует синтаксис прототипа объекта для конкретной функции, можно по-прежнему вызывать оба синтаксиса. Например, при реализации статического zeros только метод, можно вызвать:
zeros(...,'like',MyClass(...))В случае вызова синтаксиса объекта прототипа MATLAB сначала выполняет поиск метода с именем zerosLike. Если MATLAB не может найти этот метод, он вызывает zeros статический метод.
Эта функция полезна, если для создания массива необходимо только имя класса. Нет необходимости реализовывать оба метода для поддержки полного синтаксиса функции создания массива. При реализации только синтаксиса имени класса вызов синтаксиса прототипа объекта совпадает с вызовом синтаксиса имени класса.
Используйте два отдельных метода для поддержки функции создания массива. Один метод реализует синтаксис имени класса, а другой - синтаксис объекта прототипа.
Например, для поддержки zeros функция:
Реализовать синтаксис имени класса:
zeros(...,'ClassName')
Как Static способ:
methods (Static) function z = zeros(varargin) ... end end
Реализовать синтаксис объекта прототипа:
zeros(...,'like',obj)Как Hidden с помощью char вектор 'Like' добавлено к имени.
methods (Hidden) function z = zerosLike(obj,varargin) ... end end
Специальная поддержка функций создания массива является результатом интерпретации синтаксиса.
Вызов zeros функция этой формы:
zeros(...,'ClassName')
Вызывает статический метод класса со следующим синтаксисом:
ClassName.zeros(varargin{1:end-1})Вызов zeros функция этой формы:
zeros(...,'like',obj)Вызывает метод класса со следующим синтаксисом:
zerosLike(obj,varargin{1:end-2})Входные аргументы функции создания массива могут включать измерения массива, возвращаемого функцией, и, возможно, другие аргументы. В общем, существует три случая, которые должны поддерживать ваши методы:
Нет входных аргументов измерения, приводящих к возврату скаляра. Например:
z = zeros('MyClass');Один или несколько размеров равны нулю или меньше нуля, что приводит к появлению пустого массива. Например:
z = zeros(2,0,'MyClass');Любое количество допустимых размеров массива, указывающих размер массива. Например:
z = zeros(2,3,5,'MyClass');Когда функция создания массива вызывает метод класса, она передает входные аргументы, исключая имя класса или литерал 'like' и переменная объекта для метода. Методы можно реализовать с помощью следующих сигнатур:
zeros(varargin) для методов «имя класса»
zeros(obj,varargin) для методов «like prototype object»
Color класс представляет цвет в определенном цветовом пространстве, например, RGB, HSVи так далее. При обсуждении реализаций метода имени класса и реализации метода прототипа объекта этот класс используется в качестве основы для реализаций перегруженного метода.
classdef Color properties ColorValues = [0,0,0] ColorSpace = 'RGB' end methods function obj = Color(cSpace,values) if nargin > 0 obj.ColorSpace = cSpace; obj.ColorValues = values; end end end end
zeros функция снимает окончательный ClassName
char и использует его для формирования вызова статического метода в Color класс. Аргументы, передаваемые статическому методу, являются аргументами измерения массива.
Вот реализация zeros метод для Color класс. Эта реализация:
Определяет zeros метод как Static (обязательно)
Возвращает скаляр Color объект, если вызов zeros не имеет аргументов измерения
Возвращает пустой массив, если вызов zeros имеет любые аргументы размерности, равные 0.
Возвращает массив по умолчанию Color объекты. Использовать repmat для создания массива размеров, указанных вызовом zeros.
classdef Color ... methods (Static) function z = zeros(varargin) if (nargin == 0) % For zeros('Color') z = Color; elseif any([varargin{:}] <= 0) % For zeros with any dimension <= 0 z = Color.empty(varargin{:}); else % For zeros(m,n,...,'Color') % Use property default values z = repmat(Color,varargin{:}); end end end end
zeros метод использует значения по умолчанию для ColorValues , поскольку эти значения подходят для данного приложения. Осуществление ones метод может установить ColorValues свойство для [1,1,1], например.
Предположим, что требуется перегрузить randi выполнение следующих задач:
Определить каждый ColorValue свойство как массив 1 на 3 в диапазоне от 1 до указанного максимального значения (например, 1-255).
Приспосабливайте скалярные, пустые и многомерные размеры массива.
Возврат массива Color объекты указанных размеров, каждый со случайными ColorValues.
classdef Color ... methods (Static) function r = randi(varargin) if (nargin == 0) % For randi('ClassName') r = Color('RGB',randi(255,[1,3])); elseif any([varargin{2:end}] <= 0) % For randi with any dimension <= 0 r = Color.empty(varargin{2:end}); else % For randi(max,m,n,...,'ClassName') if numel([varargin{:}]) < 2 error('Not enough input arguments') end dims = [varargin{2:end}]; r = zeros(dims,'Color'); for k = 1:prod(dims) r(k) = Color('RGB',randi(varargin{1},[1,3])); end end end end end
Цель метода, возвращающего массив объектов, «похожих на объект прототипа», зависит от требований класса. Для Color класс, zeroLike создает объекты, имеющие ColorSpace значение свойства объекта прототипа, но ColorValues все равны нулю.
Вот реализация zerosLike метод для Color класс. Эта реализация:
Определяет zerosLike метод как Hidden
Возвращает скаляр Color объект, если вызов zeros функция не имеет аргументов измерения
Возвращает пустой массив, если вызов zeros имеет любые аргументы измерения, отрицательные или равные 0.
Возвращает массив Color объектов размеров, указанных вызовом zeros функция.
classdef Color ... methods (Hidden) function z = zerosLike(obj,varargin) if nargin == 1 % For zeros('like',obj) cSpace = obj.ColorSpace; z = Color; z.ColorSpace = cSpace; elseif any([varargin{:}] <= 0) % For zeros with any dimension <= 0 z = Color.empty(varargin{:}); else % For zeros(m,n,...,'like',obj) if ~isscalar(obj) error('Prototype object must be scalar') end obj = Color(obj.ColorSpace,zeros(1,3,'like',obj.ColorValues)); z = repmat(obj,varargin{:}); end end end end
Вот Color определение класса с перегруженными методами.
Примечание
На практике, Color класс требует проверки ошибок, преобразования цветового пространства и т. д. Эта чрезмерно упрощенная версия иллюстрирует реализацию перегруженных методов.
classdef Color properties ColorValues = [0,0,0] ColorSpace = 'RGB' end methods function obj = Color(cSpace,values) if nargin > 0 obj.ColorSpace = cSpace; obj.ColorValues = values; end end end methods (Static) function z = zeros(varargin) if (nargin == 0) % For zeros('ClassName') z = Color; elseif any([varargin{:}] <= 0) % For zeros with any dimension <= 0 z = Color.empty(varargin{:}); else % For zeros(m,n,...,'ClassName') % Use property default values z = repmat(Color,varargin{:}); end end function r = randi(varargin) if (nargin == 0) % For randi('ClassName') r = Color('RGB',randi(255,[1,3])); elseif any([varargin{2:end}] <= 0) % For randi with any dimension <= 0 r = Color.empty(varargin{2:end}); else % For randi(max,m,n,...,'ClassName') if numel([varargin{:}]) < 2 error('Not enough input arguments') end dims = [varargin{2:end}]; r = zeros(dims,'Color'); for k = 1:prod(dims) r(k) = Color('RGB',randi(varargin{1},[1,3])); end end end end methods (Hidden) function z = zerosLike(obj,varargin) if nargin == 1 % For zeros('like',obj) cSpace = obj.ColorSpace; z = Color; z.ColorSpace = cSpace; elseif any([varargin{:}] <= 0) % For zeros with any dimension <= 0 z = Color.empty(varargin{:}); else % For zeros(m,n,...,'like',obj) if ~isscalar(obj) error('Prototype object must be scalar') end obj = Color(obj.ColorSpace,zeros(1,3,'like',obj.ColorValues)); z = repmat(obj,varargin{:}); end end end end