How to Define Handle-Compatible Classes
What Is Handle Compatibility?
A class is handle compatible if:
It is a handle class
HandleCompatibleattribute is set to
HandleCompatible class attribute identifies classes that you can combine with handle classes when specifying a set of superclasses.
Handle compatibility provides greater flexibility when defining abstract superclasses. For example, when using superclasses that support both handle and value subclasses, handle compatibility removes the need to define both a handle version and a nonhandle version of a class.
A Handle Compatible Class
Utility class is useful to both handle and value subclasses. In this example, the
Utility class defines a method to reset property values to the default values defined in the respective class definition:
classdef (HandleCompatible) Utility methods function obj = resetDefaults(obj) mc = metaclass(obj); mp = mc.PropertyList; for k=1:length(mp) if mp(k).HasDefault && ~strcmp(mp(k).SetAccess,'private') obj.(mp(k).Name) = mp(k).DefaultValue; end end end end end
Utility class is handle compatible. Therefore, you can use it in the derivation of classes that are either handle classes or value classes. See Class Introspection and Metadata for information on using meta-data classes.
Return Modified Objects
resetDefaults method defined by the
Utility class returns the object it modifies. When you call
resetDefaults with a value object, the method must return the modified object. It is important to implement methods that work with both handle and value objects in a handle compatible superclass. See Object Modification for more information on modifying handle and value objects.
Consider the behavior of a value class that subclasses the
Utility class. The
PropertyDefaults class defines three properties, all of which have default values:
classdef PropertyDefaults < Utility properties p1 = datestr(rem(now,1)) % Current time p2 = 'red' % Character vector p3 = pi/2 % Result of division operation end end
PropertyDefaults object. MATLAB® evaluates the expressions assigned as default property values when the class is first loaded. MATLAB uses these same default values whenever you create an instance of this class in the current MATLAB session.
pd = PropertyDefaults
pd = PropertyDefaults with properties: p1: ' 4:42 PM' p2: 'red' p3: 1.5708
Assign new values that are different from the default values:
pd.p1 = datestr(rem(now,1)); pd.p2 = 'green'; pd.p3 = pi/4;
pd object property values now contain values that are different from the default values originally defined by the class:
pd = PropertyDefaults with properties: : p1: ' 4:45 PM' p2: 'green' p3: 0.7854
resetDefaults method, which is inherited from the
Utility class. Because the
PropertyDefaults class is not a handle class, return the modified object.
pd = pd.resetDefaults
pd = PropertyDefaults with properties: p1: ' 4:54 PM' p2: 'red' p3: 1.5708
PropertyDefaults class was a handle class, then you would not need to save the object returned by the
resetDefaults method. To design a handle compatible class like
Utility, ensure that all methods work with both kinds of classes.
Subclassing Handle-Compatible Classes
According to the rules described in Handle Compatibility Rules, when you combine a handle superclass with a handle-compatible superclass, the result is a handle subclass, which is handle compatible.
However, subclassing a handle-compatible class does not necessarily result in the subclass being handle compatible. Consider the following two cases, which demonstrate two possible results.
Combine Nonhandle Utility Class with Handle Classes
Suppose that you define a class that subclasses a handle class, and the handle compatible
Utility class discussed in A Handle Compatible Class. The
HPropertyDefaults class has these characteristics:
It is a handle class (it derives from
All its superclasses are handle compatible (handle classes are handle compatible by definition).
classdef HPropertyDefaults < handle & Utility properties GraphPrim = line Width = 1.5 Color = 'black' end end
HPropertyDefaults class is handle compatible:
hpd = HPropertyDefaults; mc = metaclass(hpd); mc.HandleCompatible
ans = 1
Nonhandle Subclasses of a Handle-Compatible Class
If you subclass both a value class that is not handle compatible and a handle compatible class, the subclass is a nonhandle compatible value class. The
Is a value class (it does not derive from
One of its superclasses is handle compatible (the
classdef ValueSub < MException & Utility methods function obj = ValueSub(str1,str2) obj = obj@MException(str1,str2); end end end
ValueSub class is a nonhandle-compatible value class because the
MException class does not define the
HandleCompatible attribute as
hv = ValueSub('MATLAB:narginchk:notEnoughInputs',... 'Not enough input arguments.'); mc = metaclass(hv); mc.HandleCompatible
ans = 0