Подтвердить что ты не робот

Могу ли я назначать типы свойствам класса в MATLAB?

Я новичок в использовании MATLAB в качестве объектно-ориентированной среды, и я пишу свой первый класс для описания сетевого пакета. Простой пример:

classdef Packet

    properties
        HeaderLength
        PayloadLength
        PacketType
    end

end

Я хотел бы явно указать, что HeaderLength и PayloadLength являются uint16, а PacketType - строкой. Есть ли способ сделать это?

4b9b3361

Ответ 1

Для обеспечения свойств типов существует недокументированный синтаксис:

classdef Packet
    properties
        [email protected]
        [email protected] = uint16(0);
        [email protected]
    end
end

Если вы попытаетесь установить свойство с неправильным типом, вы получите сообщение об ошибке:

>> p = Packet;
>> p.PacketType = 'tcp';
>> p.HeaderLength = 100;
While setting the 'HeaderLength' property of Packet:
Value must be 'uint16'.

Насколько я могу судить, этот синтаксис поддерживает все примитивные типы, такие как: char, int32, double, struct, cell, ..., в дополнение к любым пользовательским (просто используйте любое имя класса).

Обратите внимание, что установка типа, как указано выше, переопределяет любой "метод набора", если таковой имеется.

Я просто наткнулся на этот синтаксис, используемый во внутреннем классе в R2013a (toolboxdir('matlab')\graphics\+graphics\+internal\+figfile\@FigFile\FigFile.m), но он также работал в R2012a, вероятно, и в старых версиях...

Ответ 2

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

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

Например

classdef myClass
   properties
      myProperty = uint16(23); %# specify default value using correct type
   end
   methods
      function obj = set.myProperty(obj,val)
         if ~isa(val,'uint16')
            error('only uint16 values allowed')
         end
         %# assign the value
         obj.myProperty = val;
      end
   end
end

Ответ 3

" Ограничить свойства значения для конкретных классов" теперь официально поддерживается с R2016a. Он работает аналогично старому недокументированному синтаксису, описанному в Amro answer.

classdef Packet
    properties
        HeaderLength uint16
        PayloadLength uint16 = uint16(0);
        PacketType char
    end
end

Совместимость с предыдущими версиями

R2016a поддерживает оба варианта синтаксиса, я не заметил различий между ними. Однако оба они немного отличаются от синтаксиса на основе "@" в R2015b:

  • В R2015b объект myProp класса MyPropClass2, унаследованный от MyPropClass1, отлично передает проверку "ограничение класса", а затем сохраняется "как есть". Итак, все работает так же, как явная проверка isa(newPropVal,MyPropClass1), добавленная в метод набора свойств MyPropClass1

  • В случае синтаксиса R2016a "Ограничить значения свойств для конкретных классов" Matlab преобразует указанный объект в указанный класс. Для этого потребуется соответствующий конструктор для MyPropClass1 и означает, что MyPropClass1 не может быть Abstract.

Пример:

classdef MyPropClass1       
   methods
       % The following method is only used in R2016a case
       function obj=MyPropClass1(val)            
       end
   end         
end

------------------------------------------------------------
classdef MyPropClass2 < MyPropClass1       
end

------------------------------------------------------------
classdef MyObjClass     
    properties
        [email protected]
    end   
end

------------------------------------------------------------
myObj = MyObjClass();
myObj.someprop = MyPropClass2;

% The following displays "MyPropClass1" in R2016a, and "MyPropClass2" in R2015b
disp(class(myObj.someprop));

Совместимость с иерархиями классов

В R2016a и R2015b квалификаторы "Ограничить свойства к конкретным классам" не могут быть переопределены во вложенных классах. Например. невозможно определить что-то вроде:

classdef MyObjClass2 < MyObjClass  
    properties
        [email protected]
    end   
end