Can I assign types to class properties in MATLAB?

I'm new to using MATLAB as an object-oriented environment and I'm writing my first class to describe a network packet. A simple example would be the following

classdef Packet

    properties
        HeaderLength
        PayloadLength
        PacketType
    end

end

I would like to explicitly specify that HeaderLength and PayloadLength are both uint16's and PacketType is a string. Is there a way to do this?

Answers


There exist an undocumented syntax to enforce property types:

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

If you try to set a property with the wrong type, you get an error:

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

As far as I can tell, this syntax support all primitive types like: char, int32, double, struct, cell, ..., in addition to any user-defined ones (just use any class name).

Note that setting the type as above seems to override any "set method" if any.

I just came across this syntax being used in an internal class in R2013a (toolboxdir('matlab')\graphics\+graphics\+internal\+figfile\@FigFile\FigFile.m), but it also worked in R2012a, probably older versions as well...


The "Restrict Property Values to Specific Classes" feature is now officially supported since R2016a. It works similarly the old undocumented syntax, described in Amro's answer.

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

Compatibility with previous versions

R2016a supports both syntax options, I've noticed no differences between them. However, they both work slightly different from the "@"-based syntax in R2015b:

  1. In R2015b, an object myProp of a class MyPropClass2, inherited from MyPropClass1, perfectly passes the "class restriction" check, and then is stored "as is". So, the whole thing works just like an explicit isa(newPropVal,MyPropClass1) check added to a property set method MyPropClass1

  2. In case of R2016a "Restrict Property Values to Specific Classes" syntax, Matlab converts said object to the specified class. This would require an appropriate constructor for MyPropClass1, and means that MyPropClass1 could not be Abstract.

Example:

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
        someprop@MyPropClass1
    end   
end

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

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

Compatibility with class hierarchies

In both R2016a and R2015b, the "Restrict Property Values to Specific Classes" qualifiers could not be re-defined in nested classes. E.g. it is not possible to define something like:

classdef MyObjClass2 < MyObjClass  
    properties
        someprop@MyPropClass2
    end   
end

Since it is not possible to explicitly specify types for variables in Matlab, you cannot do this when declaring properties.

However, you can define a set method which checks the class and either throws an error or converts the input to whatever you want.

For example

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

Need Your Help

Apply global variable to Vuejs

vue-component vue.js vuejs2

I have a javascript variable which I want to pass globally to Vue components upon instantiation thus either each registered component has it as a property or it can be accessed globally.