Search code examples
matlaboopsuperclassstatic-variables

Get Class of an Object From Superclass in Matlab


Constant properties are static properties(belongs to classes, not instances) in Matlab, like many other OOP languages. And natural way to access them is ClassName.PropName as in Matlab documentation.

However, I couldn't find a way to do ClassName.PropName from a superclass, in a scenario like this:

classdef (Abstract) Superclass < handle
    properties(Dependent)
        dependentProperty
    end

    properties (Abstract, Constant)
        constantProperty
    end

    methods
        function result = get.dependentProperty(obj)
            c = class(obj); % Here I have to get class of obj
            result = length(c.constantProperty); % to use here as `ClassName.PropName`
        end
    end
end



classdef Subclass < Superclass
    properties (Constant) 
        constantProperty  = [cellstr('a'); cellstr('b')];
    end
end

so that following commands results following outputs this:(expected output)

>> subclassInstance = Subclass()

subclassInstance = 

  Subclass with properties:

     constantProperty: {2×1 cell}
    dependentProperty: 2

>> subclassInstance.dependentProperty

ans =

     2

>> 

But instead, I get following this:(actual output)

>> subclassInstance = Subclass()

subclassInstance = 

  Subclass with properties:

    constantProperty: {2×1 cell}

>> subclassInstance.dependentProperty
Struct contents reference from a non-struct array object.

Error in Superclass/get.dependentProperty (line 13)
            result = length(c.constantProperty);

>> 

Also tried: c = metaclass(obj) which gives "No appropriate method, property, or field 'constantProperty' for class 'meta.class'."

Question: Is there any way to obtain class of an object from superclass, to be able write a statement like ClassName.PropName?


EDIT:

I know I can reach from object reference like this:

function result = get.dependentProperty(obj)
    result = length(obj.constantProperty); 
end

But this is not what I want as it makes reader to think constantProperty is an instance property. Also this is not documented in Matlab, instead documentation says ClassName.PropName and this makes me think that there must be a way.


Solution

  • The right way to do this in matlab is through the instance, as per the part of my previous answer you have now incorporated in your question. This is because matlab's object-orientation model is "instance" based.

    The constant property is an instance property; it just happens to be the same (i.e. constant) in all instances. Presumably, this is why it's called "constant", not "static": it does not refer to a single static item in memory, like in c; instead every instance is instantiated with that same constant value.

    You gain nothing by going out of your way to call it via a "class reference" (no such thing exists btw; unlike python and julia, class prototypes are not objects that can be referred to, nor do they have a type themselves).

    However, if you insist, there does happen to be a way to do this using metaclasses, since a constant property set from within the constructor will have a default value named in its metaclass profile

    subclassInstance = Subclass();
    m = metaclass(subclassInstance);
    mp = findobj (m.PropertyList, 'Name', 'constantProperty');
    mp.DefaultValue
    

    Also, to address why class(subclassInstance).constantProperty doesn't work, this is simply because the result of class(subclassInstance) is a string (whose value happens to be the classname), not a "reference" to a class (like I said, such a thing doesn't exist in matlab).

    However, if you wanted to, obviously you could use such a classname string within an eval statement, to evaluate it as if you were typing it directly in the terminal to access the constant property. So this is another way of achieving what you're after:

    eval([class(subclassInstance) '.constantProperty'])
    

    but in theory eval statements should generally be avoided unless there's no alternative.


    Short note:

    in Java this is possible by this.getClass()

    In java this is called reflection, and it's java's own mechanism for 'inspecting' objects. When you do something like myObject.getClass(), what you're returning is still not a "reference to a class prototype". It's an instance of type Class. I.e. even in java, you can't do myObject.getClass().aStaticProperty. But you can use the getFields method provided by the Class class to obtain Field objects, and inspect their value with respect to specific object instances; for static fields, this instance simply becomes the null object.