Matlab 抽象子类的意外行为
Unexpected behaviour of Matlab abstract subclass
我正在编写一些 Matlab 代码来从特定文件格式加载数据,这样我就可以以统一的方式处理加载的数据。
因此,我想使用抽象 class 来表示数据,每个可能的文件格式都有唯一的子class。
我的方案的核心是一种方法,该方法要么从文件(实现的唯一位)获取数据,要么如果数据已经加载,则将其吐出。 IE。一种延迟加载系统,因为从磁盘获取数据可能很慢...
我想在我的 Matlab 程序中设置一个摘要 class,如下所示:
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
所以总而言之,我的 superclass 中有一个方法具有所有 subclasses 应该共享的功能,但在那个方法中我调用了一个特定的实现,对每个 subclass.
然后子class看起来像这样:
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';
只更新子范围内的变量class。当 运行 代码如下时,该值不会被维护:
testdata = Data.PTUImageData('somepath');
testdata.frame(1,1);
在 subclass 中设置断点显示 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
您需要通过继承 handle
:
使您的 TCSPCImageData
成为 句柄 class
classdef TCSPCImageData < handle
在 documentation 中查找有关句柄 classes 的更多信息。
默认情况下 class 是 值 class,这意味着它将有 pass-by-值 行为。换句话说,它们的行为类似于常规数值数组:
>> a = 2;
>> b = a;
>> a = 3;
>> b
b =
2
请注意,当您更改 a
时,b
并未更改,因为 b
是 a
的 copy,不是对 a
本身的引用。它们具有按值传递行为。
另一方面,其他一些变量(如MATLAB图形变量)是handle变量,并且有pass-by-reference 行为:
>> a = figure;
>> get(a,'Name')
ans =
''
>> b = a;
>> get(b,'Name')
ans =
''
>> set(a,'Name', 'hello')
>> get(b,'Name')
ans =
hello
请注意,当您更改 a
的 属性 时,b
的 属性 也会更改,因为 b
是对 [=16= 的引用],而不是它的副本。他们有传递引用行为。
默认情况下,MATLAB classes 具有值行为。您通过从 handle
.
继承来赋予它们处理行为
PS 我很确定你不需要在 subclass PTUImageData
; 中实现方法 frame
;它应该只继承 TCSPCImageData
.
的实现
我正在编写一些 Matlab 代码来从特定文件格式加载数据,这样我就可以以统一的方式处理加载的数据。
因此,我想使用抽象 class 来表示数据,每个可能的文件格式都有唯一的子class。
我的方案的核心是一种方法,该方法要么从文件(实现的唯一位)获取数据,要么如果数据已经加载,则将其吐出。 IE。一种延迟加载系统,因为从磁盘获取数据可能很慢...
我想在我的 Matlab 程序中设置一个摘要 class,如下所示:
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
所以总而言之,我的 superclass 中有一个方法具有所有 subclasses 应该共享的功能,但在那个方法中我调用了一个特定的实现,对每个 subclass.
然后子class看起来像这样:
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';
只更新子范围内的变量class。当 运行 代码如下时,该值不会被维护:
testdata = Data.PTUImageData('somepath');
testdata.frame(1,1);
在 subclass 中设置断点显示 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
您需要通过继承 handle
:
TCSPCImageData
成为 句柄 class
classdef TCSPCImageData < handle
在 documentation 中查找有关句柄 classes 的更多信息。
默认情况下 class 是 值 class,这意味着它将有 pass-by-值 行为。换句话说,它们的行为类似于常规数值数组:
>> a = 2;
>> b = a;
>> a = 3;
>> b
b =
2
请注意,当您更改 a
时,b
并未更改,因为 b
是 a
的 copy,不是对 a
本身的引用。它们具有按值传递行为。
另一方面,其他一些变量(如MATLAB图形变量)是handle变量,并且有pass-by-reference 行为:
>> a = figure;
>> get(a,'Name')
ans =
''
>> b = a;
>> get(b,'Name')
ans =
''
>> set(a,'Name', 'hello')
>> get(b,'Name')
ans =
hello
请注意,当您更改 a
的 属性 时,b
的 属性 也会更改,因为 b
是对 [=16= 的引用],而不是它的副本。他们有传递引用行为。
默认情况下,MATLAB classes 具有值行为。您通过从 handle
.
PS 我很确定你不需要在 subclass PTUImageData
; 中实现方法 frame
;它应该只继承 TCSPCImageData
.