Конструкторы разнородного массива

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

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

Когда ошибки могут произойти

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

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

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

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

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

  • Корневой суперкласс не абстрактен и не реализует 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});

Похожие темы