How to implement MyClass that overloads all methods of a certain naitive class ?

8 views (last 30 days)
I have a class MyClass that has a numerical property Val. I want the class to overload any/all numerical functions, such that fcn(Obj) returns fcn(Obj.Val).
I can implement separately an overload of any given function (say: sin, cos, and so), but I want a generic way to essentially overload ANY numeric function. Is there a way to do it?

Accepted Answer

Matt J
Matt J on 25 Aug 2019
Edited: Matt J on 25 Aug 2019
There is no special overloading method that allows this. However, you can diminish the tedious manual work of overloading all the methods by using a code writing tool like the following:
function writeOverloads(fcnlist)
for i=1:numel(fcnlist)
disp ' '
disp(char( "function varargout=" + fcnlist{i} + "(obj,varargin)" ));
disp ' '
disp(char( " [varargout{1:nargout}] = " + fcnlist{i} + "(Obj.Val,varargin{:})" ));
disp ' '
disp 'end'
disp '
end
With this, you just need to provide a list of the methods to be overloaded, and it will print the required code to the command window. Then, you can just copy/paste them to the classdef file. E.g,
>> writeOverloads({'sin','cos','log'})
will display,
function varargout=sin(obj,varargin)
[varargout{1:nargout}] = sin(Obj.Val,varargin{:})
end
function varargout=cos(obj,varargin)
[varargout{1:nargout}] = cos(Obj.Val,varargin{:})
end
function varargout=log(obj,varargin)
[varargout{1:nargout}] = log(Obj.Val,varargin{:})
end
  3 Comments
Guillaume
Guillaume on 25 Aug 2019
royk's comment mistakenly posted as an answer moved here Use comments instead of starting new answers
thanks - much appreciated!
that will work indeed!
though I can't deny that it is a bit sad that the only way to do it is to end up with such a lengthy multi-function code...
Matt J
Matt J on 25 Aug 2019
Edited: Matt J on 25 Aug 2019
@royk,
thanks - much appreciated! ... that will work indeed!
You're welcome, but please Accept-click the answer if it addresses your question.
though I can't deny that it is a bit sad that the only way to do it is to end up with such a lengthy multi-function code...
I did mention this issue in a Mathworks Usability Study about a year ago. So, they should be aware of it and hopefully are thinking about it. But I don't know what more efficient solution might be possible.
You could use Code Folding in classdef file to hide the generic overloads and keep the essential classdef code viewable. Just put all of the generic functions in their own methods block and collapse it.

Sign in to comment.

More Answers (1)

Guillaume
Guillaume on 25 Aug 2019
You may want to derive your class from a built-in numerical type as explained here, this comes with all sorts of caveats (e.g. calling sin on your class will return the built-in type, not an object of your class) but it's the only way if you don't want to write your own overload for each function.
  2 Comments
Matt J
Matt J on 25 Aug 2019
royk's reply relocated here
Thanks! That's won't help unfortunately.
How does Matlab check if MyClass has a specific overloaded method for a given function Fcn ? Can I trick it, say by overloading ismethod to say true even if there method is not explicitly implemented ? And combine this perhaps with overloading subsref to implement a call to Obj.Fcn for any Fcn ?
Guillaume
Guillaume on 25 Aug 2019
How does Matlab check if MyClass has a specific overloaded method
Same way that any other OOP language does it, by looking at the list of functions explicitly defined by the class or any of its superclasses. It has nothing to do with ismethod and tricking ismethod wouldn't help at all for this.
In any OOP language, if you want a class to use the methods of another class, you derive from that other class. So, if you want to benefit of all the numeric functions, whatever they are, derive from a numeric type.
The other option is to recreate all these numeric functions in your class. Matt's method of generating them would certainly help, but in all likelyhood you'll still be missing a lots of functions found in various toolboxes. If you want to catch them all (including future, not yet existing, functions), again there's only one way: inheritance.
What certainly wouldn't work properly is overloading subsref. Granted, by overloading subsref you could write a check for dot indexing to see if what follows the dot is a method of a numeric type and invoke that method. However, the machinery would be complex (particularly if you've got your own methods, in particular private ones) and wouldn't help at all with the functional form of calling methods (i.e. you could catch myclass.sin, but not sin(myclass)).

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!