Разделите встроенные числовые типы на подклассы, чтобы создать настроенные типы данных, которые наследовали функциональность встроенного типа. Добавьте или измените функциональность к обеспеченному суперклассом методами класса с реализацией.
Обеспечение дополнительного хранения данных в подклассе путем определения свойств может быть полезным расширением встроенного класса данных. Однако сложение свойств к подклассу требует, чтобы подкласс задал методы, чтобы реализовать стандартные поведения массивов.
Для получения дополнительной информации смотрите Подклассы Встроенных типов MATLAB.
Когда подкласс встроенного класса задает свойства, индексация по умолчанию и конкатенация не работают. subsref по умолчанию, subsasgn, horzcat и функции vertcat не могут работать с неизвестными типами свойства и значениями. Поэтому подкласс должен задать эти поведения путем реализации этих методов.
Эта демонстрационная реализация класса ExtendDouble выводит от класса double и задает одно свойство. Определение класса ExtendDouble демонстрирует, как реализовать индексацию и конкатенацию для подклассов встроенных классов
Класс ExtendDouble задает свойство DataString содержать текст, который описывает данные. Часть суперкласса класса содержит числовые данные.
Следующие методы изменяют поведение класса ExtendDouble:
ExtendDouble — Конструктор не поддерживает синтаксис аргумента, который инициализирует свойства освободить значения.
subsref Включает преобразованную в нижний индекс ссылку на часть суперкласса подкласса, ссылку записи через точку на свойство DataString, и запись через точку ссылается на встроенные данные через имя Data.
subsasgn Включает преобразованное в нижний индекс присвоение на часть суперкласса подкласса, ссылки записи через точку на свойство DataString, и запись через точку ссылается на встроенные данные через имя Data.
horzcat Задает горизонтальную конкатенацию объектов ExtendDouble. конкатенирует часть суперкласса с помощью класса double метод horzcat и формирует массив ячеек свойств DataString.
vertcat Вертикальная конкатенация, эквивалентная из horzcat (оба требуются).
'char' ExtendDouble к конвертеру char, используемому horzcat и vertcat.
disp ExtendDouble реализует метод disp, чтобы обеспечить пользовательское отображение для объекта.
Класс ExtendDouble расширяет double и реализует методы, чтобы поддержать преобразованную в нижний индекс индексацию и конкатенацию.
classdef ExtendDouble < double properties DataString end methods function obj = ExtendDouble(data,str) if nargin == 0 data = 0; str = ''; elseif nargin == 1 str = ''; end obj = obj@double(data); obj.DataString = str; end function sref = subsref(obj,s) switch s(1).type case '.' switch s(1).subs case 'DataString' sref = obj.DataString; case 'Data' d = double(obj); if length(s)<2 sref = d; elseif length(s)>1 && strcmp(s(2).type,'()') sref = subsref(d,s(2:end)); end otherwise error('Not a supported indexing expression') end case '()' d = double(obj); newd = subsref(d,s(1:end)); sref = ExtendDouble(newd,obj.DataString); case '{}' error('Not a supported indexing expression') end end function obj = subsasgn(obj,s,b) switch s(1).type case '.' switch s(1).subs case 'DataString' obj.DataString = b; case 'Data' if length(s)<2 obj = ExtendDouble(b,obj.DataString); elseif length(s)>1 && strcmp(s(2).type,'()') d = double(obj); newd = subsasgn(d,s(2:end),b); obj = ExtendDouble(newd,obj.DataString); end otherwise error('Not a supported indexing expression') end case '()' d = double(obj); newd = subsasgn(d,s(1),b); obj = ExtendDouble(newd,obj.DataString); case '{}' error('Not a supported indexing expression') end end function newobj = horzcat(varargin) d1 = cellfun(@double,varargin,'UniformOutput',false ); data = horzcat(d1{:}); str = horzcat(cellfun(@char,varargin,'UniformOutput',false)); newobj = ExtendDouble(data,str); end function newobj = vertcat(varargin) d1 = cellfun(@double,varargin,'UniformOutput',false ); data = vertcat(d1{:}); str = vertcat(cellfun(@char,varargin,'UniformOutput',false)); newobj = ExtendDouble(data,str); end function str = char(obj) str = obj.DataString; end function disp(obj) disp(obj.DataString) disp(double(obj)) end end end
Создайте экземпляр ExtendDouble и заметьте, что отображение отличается от значения по умолчанию:
ed = ExtendDouble(1:10,'One to ten')ed =
One to ten
1 2 3 4 5 6 7 8 9 10Класс ExtendDouble наследовал методы от класса дважды. Чтобы видеть список всех открытых методов, заданных двойным классом, используйте функцию methods:
methods(double.empty)
Функция sum продолжает работать с частью суперкласса объекта:
sum(ed)
ans =
55Функция sort работает над частью суперкласса объекта:
sort(ed(10:-1:1))
ans =
1 2 3 4 5 6 7 8 9 10Арифметические операторы работают над частью суперкласса объекта:
ed.^2
ans =
1 4 9 16 25 36 49 64 81 100Поскольку класс ExtendDouble задает свойство, класс должен реализовать свой собственный subsref и методы subsasgn.
Этот класс реализует следующее, преобразованное в нижний индекс, индексируя выражения для ссылки и присвоения.
obj.DataString — получите доступ к свойству DataString.
obj.Data, obj.Data(ind) — получите доступ к данным с помощью ссылки стиля свойства. Ссылка возвращает значения типа double.
obj(ind) — получите доступ к числовым данным (то же самое как obj.Data(ind)). Ссылка возвращает значения типа ExtendDouble.
Класс метод subsref позволяет вам использовать объекты ExtendDouble как числовые массивы, чтобы сослаться на числовые данные:
ed = ExtendDouble(1:10,'One to ten');
ed(10:-1:1)ans =
One to ten
10 9 8 7 6 5 4 3 2 1Доступ к числовым данным ExtendDouble, использующего индексацию стиля свойства с произвольно выбранным именем Data:
ed.Data(10:-1:1)
ans =
One to ten
10 9 8 7 6 5 4 3 2 1Доступ к свойству DataString:
ed.DataString
ans = One to ten
Преобразованное в нижний индекс присвоение реализует подобный синтаксис в классе метод subsasgn.
ed = ExtendDouble(1:10,'One to ten'); ed(11:13) = [11,12,13]; ed.DataString = 'one to thirteen'; ed
ed =
One to thirteen'
1 2 3 4 5 6 7 8 9 10 11 12 13ExtendDouble наследовал методы конвертера от двойного класса. Например, MATLAB® вызывает метод char, чтобы выполнить этот оператор присваивания.
ed(11:13) = ['a','b','c']
ed =
one to thirteen
1 2 3 4 5 6 7 8 9 10 97 98 99
ExtendDouble реализует две формы индексируемой ссылки в методе subsref:
obj.Data и obj.Data(ind) — Возвращаемые значения класса double
obj(ind) — Возвращаемые значения класса ExtendDouble
Например, сравните значения, возвращенные этими выражениями.
ed = ExtendDouble(1:10,'One to ten');
a = ed(1)a =
One to ten
1b = ed.Data(1)
b =
1whos
Name Size Bytes Class Attributes a 1x1 132 ExtendDouble b 1x1 8 double ed 1x10 204 ExtendDouble
Увеличенная гибкость реализации индексируемой ссылки в классе ExtendDouble.
Создайте эти два объекта:
ed1 = ExtendDouble([1:10],'One to ten'); ed2 = ExtendDouble([10:-1:1],'Ten to one');
Конкатенация этих объектов вдоль измерения по горизонтали:
hcat = [ed1,ed2]
hcat =
'One to ten' 'Ten to one'
Columns 1 through 13
1 2 3 4 5 6 7 8 9 10 10 9 8
Columns 14 through 20
7 6 5 4 3 2 1whos
Name Size Bytes Class Attributes ed1 1x10 204 ExtendDouble ed2 1x10 204 ExtendDouble hcat 1x20 528 ExtendDouble
Вертикальная конкатенация работает похожим способом:
vcat = [ed1;ed2]
vcat =
'One to ten' 'Ten to one'
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1И horzcat и vertcat возвращают новый объект того же класса как подкласс.