Подклассы встроенных типов со свойствами

Специализированные числовые типы с дополнительным хранением данных

Разделите встроенные числовые типы на подклассы, чтобы создать настроенные типы данных, которые наследовали функциональность встроенного типа. Добавьте или измените функциональность к обеспеченному суперклассом методами класса с реализацией.

Обеспечение дополнительного хранения данных в подклассе путем определения свойств может быть полезным расширением встроенного класса данных. Однако сложение свойств к подклассу требует, чтобы подкласс задал методы, чтобы реализовать стандартные поведения массивов.

Для получения дополнительной информации смотрите Подклассы Встроенных типов 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

Создайте экземпляр 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    13

ExtendDouble наследовал методы конвертера от двойного класса. Например, 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
     1
b = ed.Data(1)
b =

     1
whos
  Name      Size            Bytes  Class           Attributes

  a         1x1               132  ExtendDouble              
  b         1x1                 8  double                    
  ed        1x10              204  ExtendDouble              

Увеличенная гибкость реализации индексируемой ссылки в классе 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     1
whos
  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 возвращают новый объект того же класса как подкласс.

Похожие темы

Была ли эта тема полезной?