Разнородные массивы

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

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

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

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

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

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

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

В сложение любое из следующих значений верно:

  • Корневой суперкласс не абстрактен и не реализует 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 выставления счетов свойство.

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

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

The 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

The 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

The 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

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

The 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});

Похожие темы