Subclassing built-in numeric datatypes with multiple inheritance

3 views (last 30 days)
I wish to write to files the values of the variables of different types with different formats. Each variable has an associated format. Two variables of the same type might have different associated formats. I can keep a hash table with those associations (variable name and its printing format), but I would prefer to keep that information with each variable. I want each variable to behave like the original from which it is subclassed plus have some extra information in it. I tried to subclass from int32 and double then append an extra property:
classdef num < int32 & double
properties
value
print_formats = {'f1','f2','f3'};
print_format
end
methods
function obj = num( val )
switch class( val )
case 'int32'
obj = obj@int32( val );
case 'double'
obj = obj@double( val );
end
obj.print_format = obj.print_formats{ 1 };
end
end
end
This does not work:
>> x = num( 3 )
Error using num
Error: File: num.m Line: 11 Column: 31
A constructor call to superclass int32 is not a top-level statement.
This is because in Matlab there can only be one inconditional call to the supercall constructor. Avoiding this using eval:
obj = eval( [ 'obj@' class( val ) '( val )' ] );
does not work either because I have a clash of methods names in the superclasses:
>> x = num( 3 )
Error using num
Method 'isempty' defined in class 'num' has 2 or more conflicting definitions.
Is there a way to make it work through oop? Is there a better way to do what I want to?

Answers (1)

Adam
Adam on 30 Jun 2015
You definitely don't want to be subclassing two builtin types. I've only tried subclassing a builtin like that once recently as I've rarely found a use for it, but the 'value' is managed by the base class so you wouldn't want your own 'value' property and you also wouldn't want two base classes managing the property.
As you found you cannot have a conditional call to a base class constructor.
I'm not sure if I fully understand your problem, but I would probably leave the doubles and ints as they are and just create a class that takes either of these as argument and determines the format from that rather than trying to have a class that is either one or two distinct types via inheritance.
Or I would create a class to inherit from double and another to inherit from int32.
One of the reasons I have never found this type of inheritance useful though is that when you do a standard operation on your base type (e.g. addition) you just get the base type back as the result, not your derived type. This means that you lose your associated properties on the returned value.
  2 Comments
Adam
Adam on 30 Jun 2015
Thank you very much for your answer and your comments. It was only an example to use int32 and double, and when first troubles surfaced. I want my class to inherit from all numeric classes in Matlab. As I said, I can not infer the desired format from the class type, as different variables of the same class may need to be printed in different ways, so this need to be as per-variable and not per-class association.
I know I will lose my properties after any operation, but this is OK, I only need to know the print format associated to the original variable. It is even desirable, because it makes no sense, for example during multiplication, to pass more than one format to the result.
I imagine my other option is to subclass each numeric class separately, but this will be a lot of repetitive coding (I might write some generating code for it, though) and also I need to be sure all classes have the given property (or properties, if I extend this in the future), so this probably calls for another superclass. Uff, I was hoping for a cleaner solution without having to generate so many new classes.
The hastable is just quick and dirty solution, becase everytime I add a new variable, I need to remember to update the hashtable and the portability of the code is zero. If the print format property could be included into the variable itself, then it will be a required parameter upon variable creation.
Adam
Adam on 30 Jun 2015
You should definitely put as much common code in a single base class as possible, but you would only want one base class there and the you may end up with a lot of subclasses, but they should each do the minimum possible to provide the functionality that is different, not repeat the functionality that is the same.
The problem with what you are trying to do is that inheritance models an "is a" relationship and therefore multiple inheritance is used to model multiple "is a" relationships concurrently, not as alternatives.
If you could inherit from all base numeric types what you would be saying is that your derived class is every single one of those at the same time. That is definitely not desirable (and I assume is made impossible by the language because most functions would get multiply inherited and clash.
Unfortunately I don't quite understand the problem well enough to suggest much of a better solution beyond the generic that I have suggested - i.e. create your own base class with as much common behaviour as possible and as many subclasses as you need for different types and print format combinations, but keep them all lightweight, each containing only the behaviour that is different.
In terms of inheriting all the functionality of a e.g. double you may just have to accept doing e.g.
min( num.value )
instead of
min( num )
as you would be able to do if num inherits from double. This way value can be any builtin type and you can still call all functions of that type on it, it's just a bit less neat of course since you are extracting a value out of your object to operate on rather than operating on it via class methods.

Sign in to comment.

Categories

Find more on Construct and Work with Object Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!