【问题标题】:Get Class of an Object From Superclass in MatlabMatlab中从超类中获取对象的类
【发布时间】:2023-03-20 07:46:01
【问题描述】:

与许多其他 OOP 语言一样,常量属性是 Matlab 中的静态属性(属于类,而不是实例)。访问它们的自然方式是ClassName.PropName,如Matlab documentation

但是,在这样的场景中,我找不到从超类执行 ClassName.PropName 的方法:

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

因此以下命令会导致以下输出:(预期输出

>> subclassInstance = Subclass()

subclassInstance = 

  Subclass with properties:

     constantProperty: {2×1 cell}
    dependentProperty: 2

>> subclassInstance.dependentProperty

ans =

     2

>> 

但相反,我得到了以下信息:(实际输出)

>> 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);

>> 

还尝试过:c = metaclass(obj) 给出“没有适当的方法、属性或字段‘constantProperty’ 类'meta.class'。”

问题:有没有办法从超类中获取对象的类,以便能够写出像ClassName.PropName这样的语句?


编辑:

我知道我可以像这样从对象引用中到达:

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

但这不是我想要的,因为它让读者认为constantProperty 是一个实例属性。这也没有在 Matlab 中记录,而是在文档中说 ClassName.PropName,这让我认为必须有办法。

【问题讨论】:

    标签: matlab oop superclass static-variables


    【解决方案1】:

    在 matlab 中执行此操作的 正确 方法是通过实例,根据我之前回答的部分,您现在已将其纳入您的问题。这是因为 matlab 的面向对象模型是基于“实例”的。

    常量属性一个实例属性;它恰好在所有情况下都是相同的(即恒定的)。大概这就是为什么它被称为“常量”而不是“静态”的原因:它不像 c 中那样引用内存中的单个静态项;相反,每个实例都使用相同的常量值进行实例化。

    通过“类引用”来调用它,你一无所获(顺便说一句,不存在这样的东西;与 python 和 julia 不同,类原型不是可以引用的对象,它们也没有类型自己)。

    但是,如果您坚持,确实碰巧有一种方法可以使用元类来做到这一点,因为在构造函数中设置的常量属性将具有在其元类配置文件中命名的默认值 p>

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

    另外,为了解决class(subclassInstance).constantProperty 不起作用的原因,这仅仅是因为class(subclassInstance) 的结果是一个字符串(其值恰好是类名),而不是一个“引用" 上课(就像我说的,这样的东西在 matlab 中不存在)。

    但是,如果您愿意,显然您可以在 eval 语句中使用这样的类名 string 来评估它,就好像您直接在终端中键入它来访问常量属性一样。所以这是实现你所追求的另一种方式:

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

    但理论上应该避免使用eval 语句,除非别无选择。


    简短说明:

    在 Java 中,这可以通过 this.getClass() 实现

    在 java 中这称为reflection,它是 java 自己的“检查”对象的机制。当您执行myObject.getClass() 之类的操作时,您返回的是仍然,而不是“对类原型的引用”。这是Class 类型的实例。 IE。即使在java中,你也不能myObject.getClass().aStaticProperty。但是您可以使用Class 类提供的getFields 方法来获取Field 对象,并针对特定对象实例检查它们的值;对于静态字段,此实例简单地成为null 对象。

    【讨论】:

    • 我知道我可以从物体到达。然而,Matlab 文档告诉我,我可以从类参考中获得。另外,从对象到达是丑陋的,让读者认为constantProperty 是一个实例属性。此外,在 Java 中,this.getClass() 可以做到这一点,这让我认为一定有办法。
    • 我已经更新了我的答案。希望这有助于更好地解释事情。 tl;dr:is 有办法,但这不是要走的路。使用对象,卢克!
    • mathworks.com/help/matlab/matlab_oop/… 说“不支持静态属性。请参阅持久变量。对于等效于 Java 静态最终或 C++ 静态常量属性,请使用常量属性。请参阅属性常数值”。但是是的,findobj 方法更丑,我最好使用对象引用。
    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    相关资源
    最近更新 更多