Существует несколько функций MATLAB®, которые создают массивы определенного размера и типа, такие как ones
и zeros
. Пользовательские классы могут добавить поддержку функций создания массивов, не требуя использования синтаксиса перегруженного метода.
Поддержка класса любой из функций создания массивов позволяет вам разработать код, который можно совместно использовать со встроенными и пользовательскими типами данных. Например, класс переменной x
в следующем коде может быть встроенный тип во время начального развития, и затем быть заменен пользовательским классом это прозрачно перегрузки zeros
:
cls = class(x); zArray = zeros(m,n,cls);
Функции создания массивов создают массивы определенного типа двумя способами:
Синтаксис имени класса — Задает имя класса, которое определяет тип элементов массива.
Синтаксис объекта прототипа — Обеспечивает объект прототипа что функциональное использование, чтобы определить тип и другие характеристики элементов массива.
Например:
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 использует эти аргументы, чтобы отправить соответствующему методу в вашем классе.
Следующие функции поддерживают этот вид перегрузки.
Чтобы создать массив объектов по умолчанию, которые не требуют никаких входных параметров для конструктора, затем используют синтаксис имени класса.
Чтобы создать массив объектов с определенными значениями свойств или если конструктору нужны другие входные параметры, используйте объект прототипа, чтобы предоставить эту информацию.
Классы могут поддержать и имя класса и синтаксис объекта прототипа.
Можно реализовать синтаксис имени класса с 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)
для “как объект прототипа” методы
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