1

I am going to use an example to illustrate what I mean by the question title.

I would like to define a class called namedTable, which is essentially a table with a name. However, I would like to be able to do everything I can do to tables to this new class. For example, any function applicable to tables should apply to namedTables. Or, we should be able to access namedTable columns by using the notation namedTable.variableName. Here is an example of the class definition and the logic I would like to make sure namedTable inherits all functions applicable to tables:

classdef namedTable
    properties
        rawTable
        name
    end

    methods

       % constructor method
       function obj = namedTable(T, name)
           obj.rawTable = T;
           obj.name = name;
       end


       % general inheritance of all functions applicable to tables
       if fn is any fnction which can be applied to a table:
           calculate fn(obj.rawTable)
                if this is a table, coerce it to namedTable class by using
                    obj.name, and return the namedTable created.
                else
                    output fn(obj.rawTable)
                end
       end
    end

end

I would also have liked to use something like classdef namedTable < table, but Matlab returns an error: Class 'table' is Sealed and may not be used as a superclass.

Alex
  • 15,186
  • 15
  • 73
  • 127

2 Answers2

2

If you just need to have a table with an associated name, table already gives you this ability - if a is your table, you can set a.Properties.Description, and store the name in there. You also have a.Properties.UserData, in which you can store anything you like.

On your more general question - how to create subclasses that inherit properties from superclasses - in general, you would do it in exactly the way you tried, using classdef MySubClass < MySuperClass. Unfortunately, this won't work with table, as MathWorks have made it Sealed, which is specifically to prevent you form being able to subclass it.

There are good reasons for this - particularly that table has very nonstandard behaviour in that you can reference variable names using a dot-syntax, as well as properties and methods. To implement this, MathWorks have needed to provide a nonstandard implementation of subsref and subsasgn, and it would be very difficult for you to implement a subclass of that without depending on the internals of table.

If you need to something similar, then you can use composition rather than inheritance, although this might be a bit of work in this case. Essentially you would store a table as a property of your class, and then for any feature of the underlying table that you wished to access, you would implement a corresponding method in your superclass, and pass the call through.

Community
  • 1
  • 1
Sam Roberts
  • 23,951
  • 1
  • 40
  • 64
  • Thank you for your recommendation on composition. You will see in my classdef I store the table as a property in `rawTable`. So it is as you suggest, I just need to work out a economic way of doing the pass through. – Alex Aug 21 '15 at 23:17
1

It is not a good idea to do this just to add a name. It is not easy to get all the functionality of table. To get most of the functionality of table you need to override subsref method. For example subsref you can use

    function [varargout] = subsref(obj, S)
        if strcmp(S.type, '.') && strcmp(S.subs, 'name')
            varargout{1} = obj.name;
        else
            [varargout{1:nargout}] = subsref(obj.pTable, S);
        end
    end

In the same way you also need to implement subsasgn. You would still not have tab completion for methods and properties of table. You also need to override disp method to get same display as table. save/load might have similar implications.

Navan
  • 4,407
  • 1
  • 24
  • 26