Search code examples
matlaboopconstructorsubclasssuperclass

Why am I getting the error "the constructor must preserve the class of the returned object"?


I am a little rusty with my OOP concepts in general and I'm still learning MATLAB's OOP implementation specifics. I have a subclass that inherits from a superclass. I followed MATLAB's syntax rules to call the superclass constructor as follows:

obj = obj@MySuperClass(SuperClassArguments);

I have checked other similar questions, but I seem to be missing something since my syntax seems similar to examples in other similar questions as well as what is shown in MATLAB's documentation, aside from the fact that I need to use a subclass property in making the superclass constructor call.

subClass.m file contents:

classdef subClass < superClass
    properties (Access = public)
        arg1 = 1        
    end

    methods
        function obj = subClass(arg1)
            obj = obj@superClass(arg1);
        end
    end
end

superClass.m file contents:

classdef superClass
    properties (Access = protected)
        arg2
    end

    methods
        function obj = superClass(local_arg1)
            switch local_arg1
                case 1
                    obj = functionA();
                otherwise
                    obj = functionB();
            end
        end       
    end
end
function obj = functionA(obj)
    obj.arg2 = 1;
end
function obj = functionB(obj)
    obj.arg2 = 2;
end

I'm creating the subclass object at the MATLAB command prompt as follows:

>> a = subClass(1);

And I get the error:

When constructing an instance of class 'subClass', the constructor must preserve the class of the returned object.

Any pointers on what I'm getting wrong?


Solution

  • The problem appears to be with the superClass class. When you call your functions functionA and functionB, you need to pass the current object:

    classdef superClass
      properties (Access = protected)
        arg2
      end
    
      methods
        function obj = superClass(local_arg1)
          switch local_arg1
            case 1
              obj = functionA(obj);
              %Or: obj = obj.functionA();
            otherwise
              obj = functionB(obj);
              %Or: obj = obj.functionB();
          end
        end
      end
    
      methods (Access = private)
        function obj = functionA(obj)
          obj.arg2 = 1;
        end
        function obj = functionB(obj)
          obj.arg2 = 2;
        end
      end
    end
    

    I would also suggest including those functions in a method block for the class (instead of as local functions in the file) as that is the typical format for a single-file class definition. As a local function, I believe they would default to protected/private methods, as they are not visible using methods. Also, having them in a method block allows you to use the obj.functionA() syntax to invoke them, which is apparently not allowed when they are defined as local functions.