Matlab抽象子类的意外行为

时间:2015-08-17 07:48:32

标签: matlab oop abstract-class

我正在编写一些Matlab代码来加载特定文件格式的数据,以便我可以统一处理加载的数据。

因此,我希望使用具有每种可能文件格式的唯一子类的抽象类来表示数据。

我的方案的核心是一种从文件中获取数据的方法(实现的唯一位),或者,如果数据已经加载,则只是将其吐出。即一种延迟加载系统,因为从磁盘获取数据可能很慢......

我想在我的Matlab程序中设置一个抽象类,如下所示:

classdef TCSPCImageData

properties (SetAccess = protected)
    % The same for all subclasses.
    frameindex = -1;
    framedata = '';
    ...
end

properties (Abstract, SetAccess = protected)

    % Needs to be set by subclass
    type
end

methods
    % Constructor. Code omitted for brevity
    function obj = TCSPCImageData(path)
        ...
    end

    function data = frame(obj, idx, tshift)
        % Some shared functionality.
        if (obj.frameindex == idx)
            ...
        else
            % Call a specific subclass method.
            data = obj.getframe(idx,tshift);
        end
    end

end

methods (Abstract, Access = protected)
    % The abstract method that will be implemented by each subclass.
    getframe(obj, idx, tshift)
end
end

总而言之,我的超类中有一个方法具有所有子类应该共享的功能,但在该方法中我调用了一个特定的实现,对每个子类都是唯一的。

然后子类看起来像这样:

classdef PTUImageData < Data.TCSPCImageData

properties (SetAccess = protected)

    % Specific initialisation of this variable
    type = 'PTU';

end

methods

    % We call the superclass constructor.
    function obj = PTUImageData(path)

        obj@Data.TCSPCImageData(path);

    end

    % Apparently, you need to call the superclass method.
    function data = frame(obj, idx, tshift)
        data = frame@Data.TCSPCImageData(obj, idx, tshift);
    end

end

methods(Access = protected)

    % The specific implementation.
    function data = getframe(obj, idx, tshift)

        obj.framedata = 'some value';

    end

end
end

天真地,我认为这应该很好用。

但是,obj.framedata = 'some value';仅更新子类范围内的变量。运行此代码时不会保持该值,如下所示:

testdata = Data.PTUImageData('somepath');
testdata.frame(1,1);

在子类中设置断点显示obj.framedata已设置但如果我稍后检查我的testdata对象,则testdata.framedata将为空,这是完全出乎意料的。

谁可以向我展示我的方式错误?

修改

如下面的答案中所述,无需明确调用frame函数:

classdef PTUImageData < Data.TCSPCImageData

    properties (SetAccess = protected)

        % Specific initialisation of this variable
        type = 'PTU';

    end

    methods

        % We call the superclass constructor.
        function obj = PTUImageData(path)

        obj@Data.TCSPCImageData(path);

        end

    end

    methods(Access = protected)

    % The specific implementation.
    function data = getframe(obj, idx, tshift)

        obj.framedata = 'some value';

    end

end
end

1 个答案:

答案 0 :(得分:1)

您需要通过继承TCSPCImageData来创建handle 句柄类:

classdef TCSPCImageData < handle

查看documentation以获取有关句柄类的更多信息。

默认情况下,类是类,这意味着它将具有按值传递行为。换句话说,它们的行为类似于常规数字数组:

>> a = 2;
>> b = a;
>> a = 3;
>> b
b = 
    2

请注意,更改ba未发生更改,因为ba副本,而非a的引用{1}}本身。它们具有按值传递的行为。

另一方面,一些其他变量(例如MATLAB图形变量)是句柄变量,并且具有传递引用行为:

>> a = figure;
>> get(a,'Name')
ans =
     ''
>> b = a;
>> get(b,'Name')
ans =
     ''
>> set(a,'Name', 'hello')
>> get(b,'Name')
ans =
hello

请注意,当您更改b的属性时,a的属性会发生变化,因为ba的引用,而不是handle的副本。它们具有传递引用行为。

默认情况下,MATLAB类具有值行为。您可以通过继承frame来为其提供处理行为。

PS我非常确定您不应该在子类PTUImageData中实现方法TCSPCImageData;它应该从Facebook继承实现。