I'm trying to create an interface that other classes in MATLAB will inherit. This interface has a property that holds a function_handle value. The problem I'm running into is that, upon instantiating a concrete class that inherits from this class, I get the message: Error defining property 'MyFuncHandle' of class 'IMyInterfaceClass'. Unable to construct default object of class function_handle.
The interface class looks something like this:
classdef (Abstract) IMyInterfaceClass < handle
properties (Abstract)
MyFuncHandle(1,1) function_handle
end
methods (Abstract, Access = public)
% Some abstract methods declared here
end
end
With another class inheriting the interface like this:
classdef (Abstract) MyClassThatInheritsTheInterface < IMyInterfaceClass & SomeOtherAbstractClass
properties
MyFuncHandle
end
methods (Abstract)
% Some abstract methods declared here
end
methods
function this = MyClassThatInheritsTheInterface()
this@SomeOtherAbstractClass();
end
% Some concrete methods declared here
end
end
And, ultimately, a concrete subclass that inherits from MyClassThatInheritsTheInterface
.
I've tried changing the property declaration in IMyInterfaceClass
to:
properties (Abstract)
MyFuncHandle(1,1) function_handle = function_handle.empty
end
But, that doesn't work. I've also tried just setting it to a default value like this:
properties (Abstract)
MyFuncHandle(1,1) function_handle = @ode15s
end
That doesn't work either.
Is there any way to get this to work, while keeping the type-checking on MyFuncHandle
in IMyInterfaceClass
? Obviously, getting rid of the type check and leaving it as a duck-typed property would eliminate the error but would not ensure that the value in the property is a function_handle.
CodePudding user response:
I think we can distil the example down a bit to fix this issue
Abstract super class
classdef (Abstract) IMyInterfaceClass < handle
properties
MyFuncHandle(1,1) function_handle = @(varargin) disp([])
end
methods (Abstract, Access = public)
% Some abstract methods declared here
end
end
Concrete class which inherits the abstract class
classdef MyClassThatInheritsTheInterface < IMyInterfaceClass
properties
% Subclass properties
end
methods
function this = MyClassThatInheritsTheInterface()
this@IMyInterfaceClass();
end
% Some concrete methods declared here
end
end
These are pretty much lifted from your example, except I've skipped the 2nd layer of abstraction and just used one abstract superclass. The following points should still be applicable.
Note that MyFuncHandle
should only be specified in the abstract super class.
Also function_handle.empty
is, as you might expect, empty. However, you want a 1x1 function handle per your property specification. The simplest "do-nothing" function I know of which satisfies this is @(varargin) disp([])
which accepts any inputs and displays nothing. You could of course use something which instead throws an error if it's not been overwritten
@(varargin) error( 'MyFuncHandle has not been defined' );
Now you can do a = MyClassThatInheritsTheInterface();
and you will see that a.MyFuncHandle
is correctly initialised.
Perhaps the key here is that at no point does this try to class something as both an Abstract
property, whilst also giving it a value which is not consistent with it being abstract.
CodePudding user response:
Another approach is to use a validation function rather than a class/size constraint. I realise it doesn't feel quite as satisfactory, but it can be a useful approach. In this case
properties
SomeFcn {mustBeA(SomeFcn, "function_handle")}
end