A class is handle compatible if:
It is a handle class
Its HandleCompatible
attribute is set to true
The 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.
The 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
The 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.
The 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
Create a 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;
All pd
object property values now contain values that are different from the default values originally defined by the class:
pd
pd = PropertyDefaults with properties: : p1: ' 4:45 PM' p2: 'green' p3: 0.7854
Call the 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
If the 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.
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.
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 handle
).
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
The HPropertyDefaults
class is handle compatible:
hpd = HPropertyDefaults; mc = metaclass(hpd); mc.HandleCompatible
ans = 1
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 ValueSub
class:
Is a value class (it does not derive from handle
.)
One of its superclasses is handle compatible (the Utility
class).
classdef ValueSub < MException & Utility methods function obj = ValueSub(str1,str2) obj = obj@MException(str1,str2); end end end
The ValueSub
class is a nonhandle-compatible value class because the MException
class does not define the HandleCompatible
attribute as true
:
hv = ValueSub('MATLAB:narginchk:notEnoughInputs',... 'Not enough input arguments.'); mc = metaclass(hv); mc.HandleCompatible
ans = 0