Этот пример задает класс, который изменяет поведение индексации значения по умолчанию путем реализации методов subsasgn
и subsref
. Класс также реализует преобразование типов и сложение путем реализации метода конвертера double
и метода plus
.
Цель дизайна класса к:
Позвольте вам обработать объект класса как числовой массив
Смогите содержать нечисловые и числовые данные в объекте класса
Класс имеет три свойства:
Данные
числовые тестовые данные
Описание
описание тестовых данных
Дата
тест даты проводился
Примите, что у вас есть следующие случайные данные (randi
):
d = randi(9,3,4)
d = 8 9 3 9 9 6 5 2 2 1 9 9
Создайте экземпляр класса:
obj = MyDataClass(d,'Test001')
obj = MyDataClass with properties: Data: [3x4 double] Description: 'Test001' Date: [2012 1 7 9 32 34.5190]
Аргументы конструктора передают значения для свойств Data
и Description
. Функция clock
присваивает значение свойству Date
из конструктора. Этот подход получает информацию о времени и дате, когда каждый экземпляр создается.
Вот предварительный листинг кода без subsref
, subsasgn
double
и методов plus
.
classdef MyDataClass properties Data Description end properties (SetAccess = private) Date end methods function obj = MyDataClass(data,desc) if nargin > 0 obj.Data = data; end if nargin > 1 obj.Description = desc; end obj.Date = clock; end end end
Реализуйте метод subsref
, чтобы поддержать и значение по умолчанию и специализированный тип индексации.
Значение по умолчанию индексированное ссылочное поведение для скалярных объектов:
obj.Data(2,3)
ans = 5
И добавить функциональность, чтобы индексировать в свойство Data
с выражением как этот оператор:
obj(2,3)
Если вы переопределяете индексацию '()'
к доступу к поддержке к свойству Data
, вы не можете создать массивы объектов MyDataClass
и использовать индексацию '()'
, чтобы получить доступ к отдельным объектам. Можно сослаться только на скалярные объекты.
Чтобы достигнуть целей дизайна, метод subsref
должен обработать все типы индексации. Метод subsref
:
Вызывает
функцию subsref
builtin
для '.'
Индексация
Возвращает ошибку для индексации '{}'
Задает его собственную версию индексации '()'
.
Результат: obj(i)
эквивалентен obj.Data(i)
.
function sref = subsref(obj,s) % obj(i) is equivalent to obj.Data(i) switch s(1).type case '.' sref = builtin('subsref',obj,s); case '()' if length(s) < 2 sref = builtin('subsref',obj.Data,s); return else sref = builtin('subsref',obj,s); end case '{}' error('MYDataClass:subsref',... 'Not a supported subscripted reference') end end
Чтобы поддержать эквивалент индексируемого ссылочного поведения с индексируемым присвоением, реализуйте метод subsasgn
.
Поддержите индексированное присвоение значения по умолчанию:
obj.Data(2,3) = 9;
Добавьте функциональность, чтобы присвоить значения свойству Data
с выражением как этот оператор:
obj(2,3) = 9;
Как метод subsref
, метод subsasgn
:
Вызывает
функцию subsasgn
builtin
для '.'
Индексация
Возвращает ошибку для индексации '{}'
Задает его собственную версию индексации '()'
.
Функция substruct
переопределяет индексный тип, и индекс преобразовывает в нижний индекс структуру, которую MATLAB® передает subsref
и subsasgn
.
function obj = subsasgn(obj,s,val) if isempty(s) && isa(val,'MyDataClass') obj = MyDataClass(val.Data,val.Description); end switch s(1).type case '.' obj = builtin('subsasgn',obj,s,val); case '()' if length(s)<2 if isa(val,'MyDataClass') error('MyDataClass:subsasgn',... 'Object must be scalar') elseif isa(val,'double') % Redefine the struct s to make the call: obj.Data(i) snew = substruct('.','Data','()',s(1).subs(:)); obj = subsasgn(obj,snew,val); end end case '{}' error('MyDataClass:subsasgn',... 'Not a supported subscripted assignment') end end
Во-первых, реализуйте метод double
, который преобразовывает объект в массив, удваивается. Путем реализации метода конвертера double
возможно добавить объект MyDataClass
к другому классу объекта. Однако другой класс должен реализовать метод double
, который также возвращается, массив удваивается. Для получения дополнительной информации о преобразовании типов см. Преобразователи объектов.
Позвольте прямое сложение значений свойств Data
путем реализации метода plus
. Реализация метода plus
включает использование оператора +
для сложения объектов MyDataClass
.
Поскольку плюс метод реализует сложение путем добавления двойных массивов, MATLAB:
Примените правила сложения при добавлении объектов MyDataClass
Возвращает ошибки для любого условия, которое может вызвать ошибки в числовом сложении по умолчанию. Например, несоответствие размерности.
Метод plus
использует метод double
, чтобы преобразовать объект в числовые значения прежде, чем выполнить сложение:
function a = double(obj) a = obj.Data; end
function c = plus(obj,b) c = double(obj) + double(b); end
Например, метод plus
позволяет вам добавить скалярный номер к массиву объекта Data
.
Вот значения Data
, отображенное использование индексированная ссылка:
obj(:,:)
ans = 8 9 3 9 9 6 9 2 2 1 9 9
Добавьте 7
к массиву, содержавшемуся в свойстве Data
:
obj + 7
ans = 15 16 10 16 16 13 16 9 9 8 16 16
Это определение для MyDataClass
включает метод индексирования end
, обсужденный в конец как Индекс объекта.
classdef MyDataClass % Example for "A Class with Modified Indexing" properties Data Description end properties (SetAccess = private) Date end methods function obj = MyDataClass(data,desc) % Support 0-2 args if nargin > 0 obj.Data = data; end if nargin > 1 obj.Description = desc; end obj.Date = clock; end function sref = subsref(obj,s) % obj(i) is equivalent to obj.Data(i) switch s(1).type case '.' sref = builtin('subsref',obj,s); case '()' if length(s)<2 sref = builtin('subsref',obj.Data,s); return else sref = builtin('subsref',obj,s); end case '{}' error('MyDataClass:subsref',... 'Not a supported subscripted reference') end end function obj = subsasgn(obj,s,val) if isempty(s) && isa(val,'MyDataClass') obj = MyDataClass(val.Data,val.Description); end switch s(1).type case '.' obj = builtin('subsasgn',obj,s,val); case '()' % if length(s)<2 if isa(val,'MyDataClass') error('MyDataClass:subsasgn',... 'Object must be scalar') elseif isa(val,'double') snew = substruct('.','Data','()',s(1).subs(:)); obj = subsasgn(obj,snew,val); end end case '{}' error('MyDataClass:subsasgn',... 'Not a supported subscripted assignment') end end function a = double(obj) a = obj.Data; end function c = plus(obj,b) c = double(obj) + double(b); end function ind = end(obj,k,n) szd = size(obj.Data); if k < n ind = szd(k); else ind = prod(szd(k:end)); end end end end