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