Методы конструктора классов

Назначение методов конструктора классов

Метод конструктора является специальной функцией, которая создает образец класса. Обычно методы конструктора принимают входные параметры, чтобы назначить данные, хранящиеся в свойствах, и вернуть инициализированный объект.

Базовый пример см. в разделе Создание простого класса.

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

Базовая структура методов конструктора

Методы конструктора могут быть структурированы в три основных раздела:

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

  • Инициализация объекта - Вызов конструкторов суперкласса.

  • Постинициализация - Выполните любые операции, связанные с подклассом, включая ссылки и назначение объекту, методы класса вызова, передачу объекта функциям и так далее.

Этот код иллюстрирует основные операции, выполненные в каждом разделе:

classdef ConstructorDesign < BaseClass1
   properties
      ComputedValue
   end
   methods
      function obj = ConstructorDesign(a,b,c)
         
         %% Pre Initialization %%
         % Any code not using output argument (obj)
         if nargin == 0
            % Provide values for superclass constructor
            % and initialize other inputs
            a = someDefaultValue;
            args{1} = someDefaultValue;
            args{2} = someDefaultValue;
         else
            % When nargin ~= 0, assign to cell array,
            % which is passed to supclass constructor
            args{1} = b;
            args{2} = c;
         end
         compvalue = myClass.staticMethod(a);
         
         %% Object Initialization %%
         % Call superclass constructor before accessing object
         % You cannot conditionalize this statement
         obj = obj@BaseClass1(args{:});
         
         %% Post Initialization %%
         % Any code, including access to object
         obj.classMethod(arg);
         obj.ComputedValue = compvalue;
         ...
      end
   ...
   end
...
end

Вызывайте конструктор как любую функцию, передавая аргументы и возвращая объект класса.

obj = ConstructorDesign(a,b,c);

Инструкции для конструкторов

  • Конструктор имеет то же имя, что и класс.

  • Конструктор может вернуть несколько аргументов, но первым выходом должен быть созданный объект.

  • Если вы не хотите назначать выходной аргумент, можно удалить переменную объекта в конструкторе (см. «Подавленный выходной объект»).

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

  • Если ваш конструктор делает явный вызов конструктора суперкласса, этот вызов должен происходить до любой другой ссылки на построенный объект и не может происходить после return оператор.

  • Вызовы конструкторов суперкласса не могут быть условными. Вы не можете размещать вызовы конструкции суперкласса в циклах, условиях, switch, try/catch или вложенных функциях. Для получения дополнительной информации смотрите раздел «Нет условных вызовов конструкторов суперкласса».

Конструктор по умолчанию

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

Когда подкласс не задает конструктор, конструктор по умолчанию передает его входы конструктору прямого суперкласса. Это поведение полезно, когда нет необходимости в подклассе для определения конструктора, но конструктор суперкласса требует входных параметров.

Когда определять конструкторы

Задайте метод конструктора, чтобы выполнить инициализацию объекта, которую не может выполнить конструктор по умолчанию. Для примера при создании объекта класса требуется:

  • Входные параметры

  • Инициализация состояния объекта, такого как значения свойств, для каждого образца класса

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

Связанная информация

Для получения информации, относящейся к построению перечислений, см. Раздел «Последовательность вызовов конструктора классов перечисления».

Дополнительные сведения о создании объектных массивов в конструкторе см. в разделе «Построение массивов объектов».

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

Инициализация объектов в конструкторе

Методы конструктора возвращают инициализированный объект как выходной аргумент. Выходной аргумент создается, когда конструктор выполняет, перед выполнением первой строки кода.

Например, следующий конструктор может назначить значение свойства объекта A как первый оператор, поскольку объект obj уже был назначен образцу MyClass.

function obj = MyClass(a,b,c)
   obj.A = a;
   ...
end

Можно вызвать другие методы класса из конструктора, потому что объект уже инициализирован.

Конструктор также создает объект, свойства которого имеют значения по умолчанию - либо пустые ([]) или значение по умолчанию, заданное в блоке определения свойства.

Для примера этот конструктор работает с входными параметрами, чтобы присвоить значение Value свойство.

function obj = MyClass(a,b,c)
   obj.Value = (a + b) / c;
   ...
end

Ссылка на объект в конструкторе

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

% obj is the object being constructed
function obj = MyClass(arg)
   obj.propert1 = arg*10;
   obj.method1;
   ...
end

Дополнительные сведения об определении значений свойств по умолчанию см. в разделе Значений свойства по умолчанию.

Нет требования к конструктору входных аргументов

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

  • При загрузке объектов в рабочую область, если класс ConstructOnLoad для атрибута задано значение true, а load функция вызывает конструктор классов без аргументов.

  • При создании или расширении объектного массива, таким образом, чтобы не всем элементам были заданы определенные значения, конструктор классов вызывается без аргументов, чтобы заполнить неопределенные элементы (для примера, x(10,1) = MyClass(a,b,c);). В этом случае конструктор вызывается один раз без аргументов, чтобы заполнить пустые элементы массива (x(1:9,1)) с копиями этого одного объекта.

Если входных параметров нет, конструктор создает объект, используя только значения свойств по умолчанию. Хорошей практикой является добавление проверки на отсутствие аргументов в конструктор классов, чтобы предотвратить ошибку, если происходит любой из этих двух случаев:

function obj = MyClass(a,b,c)
   if  nargin > 0
      obj.A = a;
      obj.B = b;
      obj.C = c;
      ...
   end
end

Способы обработки конструкторов суперкласса смотрите в Основной структуре методов конструктора.

Конструкторы подкласса

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

classdef MyClass < SuperClass
   methods
      function obj = MyClass(a,b,c,d)
         obj@SuperClass(a,b);
         ...
      end
   end
end

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

Ссылка только на указанные суперклассы

Если на classdef не задает класс как суперкласс, конструктор не может вызвать конструктор суперкласса с этим синтаксисом. То есть конструктор подкласса может вызывать только прямые конструкторы суперкласса, перечисленные в classdef линия.

classdef MyClass < SuperClass1 & SuperClass2

MATLAB вызывает все незакрытые конструкторы в порядке слева направо, в котором они заданы в classdef линия. MATLAB не передает аргументов с этими вызовами.

Никаких условных вызовов конструкторов суперкласса

Вызовы конструкторов суперкласса должны быть безусловными. Может быть только один вызов для данного суперкласса. Инициализируйте фрагмент суперкласса объекта, вызвав конструкторы суперкласса перед использованием объекта (для примера присвоить значения свойств или вызова методы класса).

Чтобы вызвать конструктор суперкласса с различными аргументами, которые зависят от некоторых условий, создайте массив ячеек из аргументов и предоставьте один вызов конструктору.

Для примера, Cube конструктор классов вызывает суперкласс Shape конструктор, использующий значения по умолчанию, когда Cube конструктор вызывается без аргументов. Если на Cube вызывается конструктор с четырьмя входными параметрами, затем передается upvector и viewangle конструктору суперкласса:

classdef Cube < Shape
   properties
      SideLength = 0
      Color = [0 0 0]
   end
   methods
      function cubeObj = Cube(length,color,upvector,viewangle)
         % Assemble superclass constructor arguments
         if nargin == 0
            super_args{1} = [0 0 1];
            super_args{2} = 10;
         elseif nargin == 4
            super_args{1} = upvector;
            super_args{2} = viewangle;
         else
            error('Wrong number of input arguments')
         end

         % Call superclass constructor
         cubeObj@Shape(super_args{:});

         % Assign property values if provided
         if nargin > 0 
            cubeObj.SideLength = length;
            cubeObj.Color = color;
         end
         ...
      end
   ...
   end
end

Нуль или несколько аргументов суперкласса

Чтобы поддержать синтаксис, который вызывает конструктор суперкласса без аргументов, предоставьте этот синтаксис явно.

Предположим, в случае Cube пример класса, все значения свойств в Shape суперкласс и Cube подкласс имеет значения по умолчанию, заданные в определениях классов. Затем можно создать образец Cube без указания аргументов для конструкторов суперкласса или подкласса.

Вот как можно реализовать это поведение в Cube конструктор:

methods
   function cubeObj = Cube(length,color,upvector,viewangle)
      % Assemble superclass constructor arguments
      if nargin == 0 
         super_args = {};
      elseif nargin == 4
         super_args{1} = upvector;
         super_args{2} = viewangle;
      else
         error('Wrong number of input arguments')
      end

      % Call superclass constructor
      cubeObj@Shape(super_args{:});

      % Assign property values if provided
      if nargin > 0 
         cubeObj.SideLength = length;
         cubeObj.Color = color;
      end
   ...
   end
end

Подробнее о подклассах

Информацию о создании подклассов см. в разделе Конструкторы подкласса проекта.

Неявный вызов наследованного конструктора

MATLAB неявно передает аргументы из конструктора подкласса по умолчанию в конструктор суперкласса. Это поведение устраняет необходимость реализации метода конструктора для подкласса только для передачи аргументов конструктору суперкласса.

Для пример в следующем конструкторе классов требуется один входной параметр (a datetime объект), который конструктор присваивает CurrentDate свойство.

classdef BaseClassWithConstr
   properties
      CurrentDate datetime
   end
   methods
      function obj = BaseClassWithConstr(dt)
         obj.CurrentDate = dt;
      end
   end        
end

Предположим, что вы создаете подкласс BaseClassWithConstr, но ваш подкласс не требует явного метода конструктора.

classdef SubclassDefaultConstr < BaseClassWithConstr
   ...
end

Можно создать объект SubclassDefaultConstr вызывая его конструктор по умолчанию с аргументом суперкласса:

obj = SubclassDefaultConstr(datetime);

Для получения информации о конструкторах подкласса см. «Конструкторы подкласса» и «Конструктор по умолчанию».

Ошибки при конструкции классов

Для классов handle MATLAB вызывает delete метод, когда ошибка происходит при следующих условиях:

  • Ссылка на объект присутствует в коде до ошибки.

  • Раннее return оператор присутствует в коде перед ошибкой.

MATLAB вызывает delete метод для объекта, delete методы для любых объектов, содержащихся в свойствах, и delete методы для любых инициализированных базовых классов.

В зависимости от того, когда происходит ошибка, MATLAB может вызвать деструктор классов до того, как объект будет полностью построен. Поэтому классы delete методы должны иметь возможность работать с частично сконструированными объектами, которые могут не иметь значений для всех свойств. Для получения дополнительной информации смотрите Поддержка уничтожения частично построенных объектов.

Дополнительные сведения о том, как объекты уничтожаются, см. в разделе «Уничтожение классов Handle».

Выходной объект подавлен

Вы можете подавить назначение образца класса ans переменная, если никакая выходная переменная не назначена в вызове конструктору. Этот метод полезен для приложений, которые создают окна графического интерфейса, которые удерживают построенные объекты. Этим приложениям не нужно возвращать объект.

Использовать nargout чтобы определить, был ли вызван конструктор с выходным аргументом. Для примера, конструктор классов для MyApp класс очищает переменную объекта, obj, если вызывается без назначенного выхода:

classdef MyApp
   methods
      function obj = MyApp
         ...
         if nargout == 0
            clear obj
         end
      end
      ...
   end
end

Когда конструктор класса не возвращает объект, MATLAB не запускает meta.class InstanceCreated событие.

Похожие темы