Search code examples
matlaboopsubclasssuperclassaccessor

Overriding a superclass property set method within a subclass in MATLAB


I have a MATLAB class called super:

classdef super < handle

    properties
        aString = '';
    end

    methods
        function obj = super(obj, value)
            obj.aString = value;
        end

        function set.aString(obj, value)
            obj.aString = value;
        end
    end
end

I want to override the set function in a subclass derived from 'super':

classdef sub < super

    %// Property 'aString' is inherited from super

    methods
        function obj = sub(obj, value)
            %// Must include call to super constructor otherwise MATLAB will by
            %// default call constructor with no arguments but my super class
            %// requires one argument in constructor. This call should probably
            %// super set method. But I don't care.
            obj = obj@super('');

            %// Now that super constructor has returned, call sub overriding
            %// set method
            obj.aString = value;

        end

        function set.aString(obj, value)
            obj.aString = value;
        end
    end
end

The code above gives me the following error:

> Cannot define property 'aString' in class 'sub' because the property
> has already been defined in the superclass 'super'

Adding the property definition to 'sub' results in the same error.

I have also unsuccessfully tried using "Abstract" as a workaround, where I define an Abstract class:

classdef (Abstract) bloat < handle
    properties (Abstract)
        aString
    end
end

and then try implementing 'super' as a child of 'bloat':

classdef super < bloat
%// Remainder of super code remains the same

Which did not work as I guess by the time 'sub' inherites, 'aString' is "concrete". I then, in addition to the above modification, tried modifying 'sub' to include 'boat' in its class definition:

classdef sub < super & bloat
%// Remainder of super code remains the same

This also did not work.

I have been unable to find any MATLAB documentation that specifically says: "You cannot modify set and get methods".

I'm hoping that my syntax is simply incorrect, but from searching I now fear that MATLAB does not allow this (either as a bug or by design).

EDIT: I am using MATLAB 2013a

Thank you


Solution

  • Another solution is to make the set method call a protected function to perform whatever logic you need on assignment. This protected method can of course be overriden in subclasses.

    Although unrelated to the issue above, it is always preferable to have a constructor that accepts zero arguments as well your current constructor. See the changes I made in that regard.

    super.m

    classdef super < handle
        properties
            x = 1;    % some property with a default value
        end
    
        methods
            function obj = super(value)
                % allow for zero-argument construction
                if nargin > 0
                    obj.x = value;
                end
            end
            function set.x(obj, value)
                % call another function to check the value as desired,
                % and possibly even update it using some computation
                value = checkX(obj, value);
    
                % set set the property using the validated value
                % (only place we do assignment to avoid infinite recursion)
                obj.x = value;
            end
        end
    
        methods (Access = protected)
            function value = checkX(obj, value)
                % for example, we require that values be scalar positive
                validateattributes(value, {'numeric'}, {'scalar','positive'});
            end
        end
    end
    

    sub.m

    classdef sub < super
        methods
            function obj = sub(value)
                % set inherited property if requested
                if nargin > 0
                    obj.x = value;
                end
            end
        end
    
        methods (Access = protected)
            function value = checkX(obj, value)
                % we could call superclass method to combine effect
                value = checkX@super(obj, value);
    
                % or override super-class logic (example: maximum value of 10)
                value = min(value,10);
            end
        end
    end