Когда подкласс в гетерогенной иерархии классов вызывает свой суперкласс для построения массива объектов, необходимо убедиться, что конструктор суперкласса не возвращает гетерогенный массив в подкласс. Следующие шаблоны программирования показывают, как избежать ошибок, вызванных возвращением неправильного класса конструктору подкласса.
Конструкторы должны возвращать объекты того же класса, что и определяющий класс. При работе с объектами из гетерогенной иерархии классов класс массива объектов может изменяться при добавлении элементов массива различных классов. В результате гетерогенные суперклассные конструкторы могут изменять класс массивов объектов, когда для конструкции класса требуются все следующие методы:
Построение массивов объектов в конструкторах подклассов
Вызов конструкторов суперкласса из конструкторов подкласса для передачи аргументов
Создание массивов объектов в конструкторе суперкласса
Кроме того, верно любое из следующего:
Корневой суперкласс не является абстрактным и не реализует 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});