Этот пример задает класс, который изменяет поведение индексации значения по умолчанию путем реализации методов 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