Transitioning Serialization and Deserialization Processes to
            matlab.mixin.CustomElementSerialization
The recommended process for customizing serialization and
            deserialization of objects is to use the matlab.mixin.CustomElementSerialization mixin (since R2024b). Transitioning to the
         mixin from an existing implementation of loadobj and
            saveobj can give you greater control of the serialization process in
         future revisions of the class. However, some existing implementations might make
            loadobj and saveobj the better option.
Preserve Version Compatibility Between loadobj and                saveobj Implementations and
               matlab.mixin.CustomElementSerialization
The first version of the Rectangle class represents a rectangle using
            the coordinates of the lower-left and upper-right vertices. The saveobj
            and loadobj methods only handle the property data using structures.
            This implementation enables flexibility for any future class versions that use different
            properties to define the
            rectangle.
classdef Rectangle % Version 1 properties x1 y1 x2 y2 end methods function obj = Rectangle(x1,y1,x2,y2) obj.x1 = x1; obj.y1 = y1; obj.x2 = x2; obj.y2 = y2; end function s = saveobj(obj) s.x1 = obj.x1; s.y1 = obj.y1; s.x2 = obj.x2; s.y2 = obj.y2; end end methods(Static) function obj = loadobj(s) obj = Rectangle(s.x1,s.y1,s.x2,s.y2); end end end
Version 2 of the class represents the rectangle using the coordinates of the
            lower-left vertex, the height, and the width. The revision maintains compatibility by
            implementing saveobj and loadobj methods to ensure
            that Version 2 of the class can load instances saved under Version 1, and Version 1 of
            the class can load instances saved under Version 2. The constructor accepts the same
            property values of Version 1, namely the coordinates of the lower-left and upper-right
            coordinates. The loadobj method calls the Rectangle
            constructor with those values. To preserve compatibility with Version 1, the
               saveobj method converts the new properties back to the old
            properties and saves them as a structure.
            
classdef Rectangle % Version 2 properties x0 y0 width height end methods function obj = Rectangle(x1,y1,x2,y2) obj.x0 = x1; obj.y0 = y1; obj.width = x2 - x1; obj.height = y2 - y1; end function s = saveobj(obj) s.x1 = obj.x0; s.y1 = obj.y0; s.x2 = obj.x0 + obj.width; s.y2 = obj.y0 + obj.height; end end methods(Static) function obj = loadobj(s) obj = Rectangle(s.x1,s.y1,s.x2,s.y2); end end end
Version 2a of the Rectangle class is a subclass of
               matlab.mixin.CustomElementSerialization, but its behavior is
            consistent with Version 2. The modifyOutgoingSerializationContent
            method stores the data in properties consistent with Version 1 of the class. With this
            method in place:
- Both Version 1 and Version 2 of the class can load instances saved under Version 2a because the property values are stored in the original format of Version 1. 
- modifyOutgoingSerializationContentsaves the rectangle information as- x0,- y0,- width, and- heightby default, but it also saves the coordinates- x1,- x2,- y1, and- y2. Because Version 2a includes the properties and values in the same format as Versions 1 and 2, Version 2a can load an instance of any version.
classdef Rectangle < matlab.mixin.CustomElementSerialization % Version 2a properties x0 y0 width height end methods function obj = Rectangle(x1,y1,x2,y2) obj.x0 = x1; obj.y0 = y1; obj.width = x2 - x1; obj.height = y2 - y1; end end methods(Static) function modifyOutgoingSerializationContent(sObj,obj) sObj.addNameValue("x1",obj.x0); sObj.addNameValue("x2",obj.x0 + obj.width); sObj.addNameValue("y1",obj.y0); sObj.addNameValue("y2",obj.y0 + obj.height); end end end
With this new version, you can now take advantage of all of the capabilities of
               matlab.mixin.CustomElementSerialization. To check the compatibility,
            create an instance of Rectangle under Version
            2a.
test = Rectangle(1,1,4,6)
test = 
  Rectangle with properties:
        x0: 1
        y0: 1
     width: 3
    height: 5Save the instance. modifyOutgoingSerializationContent uses the
               width and height properties to define the
            second
            vertex.
save("yourfilepath/RectV2a.mat","test")Clear the instance, and then load it under Version 1.
clear test
load("yourfilepath/RectV2a.mat","test")
testtest = 
  Rectangle with properties:
    x1: 1
    y1: 1
    x2: 4
    y2: 6Private Properties with the Same Name in Class Hierarchies
Classes in a hierarchy that define private properties with the same name require
            special handling when serializing and deserializing with loadobj and
               saveobj. The Animal class and its subclass
               Pet both define a private property named ID. To
            handle both properties: 
- The - saveobjmethod of- Animalsaves its- IDproperty in the outgoing structure under the name of- AnimalIDto avoid conflicting with the- IDproperty of- Pet.
- The - loadobjmethods of both classes pass the value of- AnimalIDto the constructor to recreate the- IDproperty of- Animal.
classdef Animal properties Species end properties(Access = private) ID end methods function obj = Animal(Species,ID) obj.Species = Species; obj.ID = ID; end function s = saveobj(obj) s.Species = obj.Species; s.AnimalID = obj.ID; end end methods (Static) function obj = loadobj(s) if isstruct(s) obj = Animal(s.Species,s.AnimalID); else obj = s; end end end end
classdef Pet < Animal properties OwnerName end properties(Access = private) ID end methods function obj = Pet(Species,AnimalID,OwnerName,ID) obj@Animal(Species,AnimalID); obj.OwnerName = OwnerName; obj.ID = ID; end function s = saveobj(obj) s = saveobj@Animal(obj); s.OwnerName = obj.OwnerName; s.ID = obj.ID; end end methods(Static) function obj = loadobj(s) if isstruct(s) obj = Pet(s.Species,s.AnimalID,s.OwnerName,s.ID); else obj = s; end end end end
The matlab.mixin.CustomElementSerialization mixin enables you to
            reference private properties with the same name by preceding the property name with the
            name of the defining class and a dot. You can use this convention to transition classes
            with private property overlap to use the mixin instead of saveobj and
               loadobj.
For example, the following revised Animal class inherits from the
            mixin and implements a modifyIncomingSerializationContent method. The
               saveobj method of the original Animal stores its
               ID property as AnimalID. The
               modifyIncomingSerializationContent method checks for an
               AnimalID field in the incoming content. If
               AnimalID is part of the serialized content, the
               modifyIncomingSerializationContent method renames the property to
               Animal.ID. The rename method uses the
               className.propertyName syntax that is required for private
            properties. (For more information, see the description for rename in
               matlab.serialization.ElementSerializationContent.)
classdef Animal < matlab.mixin.CustomElementSerialization properties Species end properties (Access = private) ID end methods function obj = Animal(Species,ID) obj.Species = Species; obj.ID = ID; end end methods(Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("AnimalID") sObj.rename("AnimalID","Animal.ID"); end end end end
Pet class implements a
               modifyIncomingSerializationContent method that calls the superclass
            method to process the superclass ID property. To enable the older
            version of the class to deserialize objects saved under the new definition,
               Pet implements modifyOutgoingSerializationContent to
            save the superclass ID property as AnimalID.
            classdef Pet < Animal properties OwnerName end properties(Access = private) ID end methods function obj = Pet(Species,AnimalID,OwnerName,ID) obj@Animal(Species,AnimalID); obj.OwnerName = OwnerName; obj.ID = ID; end end methods(Static) function modifyOutgoingSerializationContent(sObj,~) sObj.addNameValue("AnimalID",sObj.getValue("Animal.ID")); sObj.remove("Animal.ID"); end function modifyIncomingSerializationContent(sObj) modifyIncomingSerializationContent@Animal(sObj) end end end
Maintaining Existing loadobj and saveobj             Implementations
In some cases, existing designs using loadobj and
               saveobj cannot be easily transitioned to a
               matlab.mixin.CustomElementSerialization design without significant
            revision of existing classes.  For example: 
- The - loadobjmethod of an existing class only accepts a structure as input. Deserializing an object under the old definition might cause warnings. To force- loadobjto deserialize the content as a structure, you can use- modifyOutgoingSerializationContentto add a property that is not part of the original class definition. The disadvantage to this method is that the added property is now stored, even though it has no meaning in either version of the class.
- The - loadobjmethod can only deserialize data from a format other than an object or a structure. For example, a class could use- saveobjto save property values in a table, and the corresponding- loadobjcan only accept a table as input. The methods of- matlab.mixin.CustomElementSerializationonly support object data, so data from the older version of the class would be inaccessible. In this case, the only workaround is to revise how the existing class definition serializes data.
In cases like these, maintaining your existing loadobj and
               saveoobj implementations might be preferable to what would be
            required to transition to matlab.mixin.CustomElementSerialization.
See Also
matlab.mixin.CustomElementSerialization | matlab.serialization.ElementSerializationContent | matlab.serialization.SerializationContext