exponenta event banner

Конструкторы гетерогенных массивов

Построение массивов в конструкторах суперкласса

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

Когда могут возникнуть ошибки

Конструкторы должны возвращать объекты того же класса, что и определяющий класс. При работе с объектами из гетерогенной иерархии классов класс массива объектов может изменяться при добавлении элементов массива различных классов. В результате гетерогенные суперклассные конструкторы могут изменять класс массивов объектов, когда для конструкции класса требуются все следующие методы:

  • Построение массивов объектов в конструкторах подклассов

  • Вызов конструкторов суперкласса из конструкторов подкласса для передачи аргументов

  • Создание массивов объектов в конструкторе суперкласса

Кроме того, верно любое из следующего:

  • Корневой суперкласс не является абстрактным и не реализует getDefaultScalarElement способ.

  • Корневой суперкласс реализует getDefaultScalarElement метод, возвращающий объект, не являющийся классом подкласса.

При назначении массивов объектов MATLAB ® использует объект по умолчанию для заполнения неназначенных элементов массива. В гетерогенной иерархии объектом по умолчанию может быть суперкласс, вызываемый конструктором подкласса. Поэтому построение массива в конструкторе суперкласса может создать гетерогенный массив.

Если конструктор суперкласса возвращает гетерогенный массив конструктору подкласса, MATLAB генерирует ошибку (см. раздел Потенциальная ошибка).

Инициализация массива в конструкторе суперкласса

Во избежание ошибок инициализируйте массив объектов явно в конструкторе суперкласса. Например, использовать repelem в конструкторе суперкласса для инициализации массива перед инициализацией части суперкласса объектов. Инициализация массива гарантирует, что все элементы, назначенные в массив, имеют тот же класс, что и obj аргумент.

В этом коде конструктор суперкласса создает один объект для каждого элемента во входном аргументе, arg:

method
   function obj = SuperClass(arg)
      ...
   n = numel(arg);
   obj = repelem(obj,1,n);
   for k = 1:n
      obj(k).SuperProp = arg(k);
   end
      ...
   end
end

Конструктор подкласса вызывает конструктор суперкласса, чтобы передать требуемый массив аргументов, a:

method
   function obj = SubClass(a)
         obj = obj@SuperClass(a);
         for k = 1:numel(a)
            obj(k).SubProp = a(k);
      end
   end
end

Пример реализации

Следующая иерархия классов определяет подкласс, который строит массивы объектов в своем конструкторе. Корневой суперкласс иерархии инициализирует суперклассную часть объектов в массиве.

Эта иерархия классов представляет членов инженерной команды. Классы в иерархии включают в себя:

  • TeamMembers - суперкласс для определенных классов участников группы, например ProjectEngineer. TeamMembers определяет Name и PhoneX свойства и производные от matlab.mixin.Heterogeneous.

  • ProjectEngineer - Члены команды - инженеры. Каждый экземпляр наследует Name и PhoneX свойство и определяет выставление счета Rate собственность.

  • Другие члены - другие типы членов коллектива, не реализованные для этого примера для простоты.

TeamMembers класс является корнем гетерогенной иерархии и конкретным классом. Перед присвоением значений Name и PhoneX свойства, конструктор инициализирует массив подкласса (ProjectEngineer) объекты.

ProjectEngineer конструктор обеспечивает obj аргумент для вызова repelem с этим утверждением:

obj = obj@TeamMembers(varargin{1:2});

Вот TeamMembers класс:

classdef TeamMembers < matlab.mixin.Heterogeneous
   properties
      Name
      PhoneX
   end
   methods
      function obj = TeamMembers(nme,ext)
         if nargin > 0
            n = numel(nme);
            obj = repelem(obj,1,n);
            for k = 1:n
               obj(k).Name = nme{k};
               obj(k).PhoneX = ext(k);
            end
         else
            obj.Name = '';
         end
      end
   end
end

ProjectEngineer класс представляет один тип участника коллектива. Этот класс поддерживает входные данные массива и возвращает массив объектов.

classdef ProjectEngineer < TeamMembers
   % Inputs: {Name}, [PhoneX], {Rate}
   properties
      Rate
   end
   methods
      function obj = ProjectEngineer(varargin)
         obj = obj@TeamMembers(varargin{1:2});
         for k = 1:numel(varargin{1})
            obj(k).Rate = varargin{3}{k};
         end
      end
   end
end

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

nm = {'Fred','Nancy','Claudette'};
px = [8112,8113,8114];
rt = {'C2','B1','A2'};
tm = ProjectEngineer(nm,px,rt)
tm = 

  1x3 ProjectEngineer array with properties:

    Rate
    Name
    PhoneX

Потенциальная ошибка

TeamMembers конструктор инициализирует массив объектов с помощью следующей инструкции:

obj = repelem(obj,1,n);

Потому что obj аргумент для repelem является ProjectEngineer , возвращаемый массив имеет тот же класс.

Без этого утверждения, TeamMembers создает объекты по умолчанию для заполнения элементов массива в for цикл. Полученный гетерогенный массив будет иметь класс общего суперкласса (TeamMembers в данном случае). Если суперкласс возвращает этот гетерогенный массив конструктору подкласса, это является нарушением правила, согласно которому конструкторы классов должны сохранять класс возвращаемого объекта.

MATLAB выдает следующую ошибку:

When constructing an instance of class 'ProjectEngineer', the constructor must
preserve the class of the returned object.

Error in ProjectEngineer (line 8)
         obj = obj@TeamMembers(varargin{1:2});

Связанные темы