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