为什么在定义MATLAB容器时“输出参数太多”。具有0输出的map子类方法?

时间:2015-03-22 14:34:09

标签: matlab oop containers subclassing

我试图通过继承它来扩展MATLAB containers.Map类,并添加一个带有0输出的附加方法,但是我遇到了"太多的输出参数"执行方法时出错。这不是特定于新方法实现的 - 任何使用0输出扩展containers.Map()的附加方法都将生成此错误。

具体而言,执行时会遇到错误,

obj = Containers();
obj.testfun();

对于以下类定义,

classdef Containers < handle & containers.Map
    methods       
        % Test function to display keys.
        function testfun(obj)
            obj.keys(); % dumby thing to execute with incoming object.
            disp('it works!');
        end
    end
end

但是,如果我们稍微修改它以输出至少一个参数,

classdef Containers < handle & containers.Map
    methods       
        % Test function to display keys.
        function dumby = testfun(obj)
            obj.keys();
            disp('it works!')
            dumby = 1;
        end
    end
end

它会正确执行。在子类化containers.Map时,错误似乎发生。如果重要,我使用的是MATLAB R2014b。有关如何解决此问题的任何建议吗?

1 个答案:

答案 0 :(得分:1)

不要尝试继承containers.Map。这只是我的意见,但是MathWorks应该已经Sealed,所以你不能这样做。

此处发生的是,当您输入a.ba(b)a{b}时,会将其转换为对方法subsref的调用。所有对象都有该方法。有关MATLAB如何调用doc subsref的详细信息,请参阅subsref,但要注意 - 它非常复杂。

现在,如果您想自定义类的行为,可以通过提供自己的实现来重载subsrefcontainers.Map这样做,因为它需要支持按键索引,这对于其他MATLAB类来说并不常见。

我无法准确地告诉您subsref containers.Map的实施方式,因为它是一个内置类,所以我无法看到代码。但是,我猜测,根据您在此处看到的行为,它在某个时候尝试确定.testfun()是否是对方法testfun的调用,或者属性testfun,或者字段testfun,或其他东西,它正在做的事情之一是查看是否使用输出参数调用它并相应地更改其行为。

这是一个很好的例子,说明如果你不知道(并且可能修改)它的内部结构,你真的无法对该对象进行子类化,这就是为什么我建议MathWorks可能更好地使这个Sealed成为阻止你尝试。在任何情况下,您都无法使用您想要的行为将其子类化,而无需一些解决方法(即为您的subsref类实现自己的重载Containers以便制作它的工作方式如你所愿)和一些逆向工程(即第二次猜测subsref containers.Map方法的内部结构。

相反,您可以尝试使用适配器模式,通过创建自己的类containers.Map作为私有(可能是隐藏)属性,然后实现只通过其参数和输出到底层的方法和属性containers.Map。最后,也要实现自己的方法。