如何在使用 MATLAB Class 文件夹创建的 class 对象中创建成员 public?
How to make a member public in an class object created using MATLAB Class folder?
我正在尝试重用一个包,其中所有 classes 都是使用 Class 文件夹编写的,即所有方法都是文件夹 @myclassname 中的文件。我想读取 class 对象的成员。在正常的 classdef classes 中,声明一个 属性 public 可以解决问题。就我而言,我没有找到任何解决方案,我不想重写整个包。
解释我的问题的最小示例:
简单 class: \MatlabPath\@mytestclass\mytestclass.m
%myconstructor
function res =mytestclass()
st.a=1;
res=class(st,mfilename);
end
当前行为:
>> obj=mytestclass();
>> obj.a
Access to an object's fields is only permitted within its methods.
期望:
>> obj=mytestclass();
>> obj.a
ans =
1
谢谢
我知道您不想重写整个包,但如果 属性 访问很重要,您可能更喜欢它而不是实际的解决方案。
在第一个 MATLAB OOP classes 中,按照您的指示进行组织(所有方法都在一个文件夹中),程序员必须编写自己的 subsref
and subsasgn
方法,如果他们想要自定义访问他们的 class属性。
我必须说我确实玩过它,但很快就放弃了,因为构建简单的 classes 非常乏味。 MATLAB 可能注意到了这一点,并在后来的版本中引入了新的 Classdef
模型。尽管仍然有一些快速(由于 MATLAB 按值传递几乎所有内容),这个 Classdef
模型比旧公式更方便。
如果你想坚持使用旧模型,我可以给你一个极简主义的例子,它会给你想要的行为。如果您只对公开一些属性感兴趣,您可以复制几次。如果您打算公开包的所有属性,那么我向您保证,重写包比将我的解决方案应用于广泛的现有代码库更省力。
因此在您的文件夹中:\MatlabPath\@mytestclass\
,您现在需要两个文件:
mytestclass.m
(例如,我添加了几个不同的属性)
function res =mytestclass()
st.scalar = 1 ;
st.array = [1 2 3] ;
st.cellarray = {'1' '2' '3'} ;
res=class(st,mfilename);
end
和你自己的 subsref.m
:
function out = subsref(obj,S)
thisS = S(1) ;
if strcmp(thisS.type , '.')
out = obj.(thisS.subs) ;
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
end
% recursive call if the struct S has more than one element
if numel(S) > 1
S(1) = [] ;
out = subsref(out,S) ;
end
end
有了它,您现在可以访问您的属性:
>> obj.scalar
ans =
1
>> obj.array
ans =
1 2 3
>> obj.cellarray
ans =
'1' '2' '3'
这个最小的 subsref
也适用于对数组进行索引:
>> obj.array(2:end)
ans =
2 3
>> obj.cellarray(2)
ans =
'2'
它也适用于赋值:
>> obj.scalar = 125 ;
>> obj.scalar
ans =
125
>> obj.array(2:end) = [8 9] ;
>> obj.array
ans =
1 8 9
请记住,这是一个最小的示例,某些 属性 类型可能无法很好地响应这些简单的情况,在这种情况下,您将必须添加特定的代码来处理每个特定的情况。
给出了正确的解决方案,并允许自定义可以访问的成员。您甚至可以设计 class,这样您就可以 'index' 使用不匹配任何成员的名称。
但是如果你只想公开所有 class 成员,你可以将 subsref
函数简化为:
function out = subsref(obj,S)
out = builtin('subsref',obj,S);
我正在尝试重用一个包,其中所有 classes 都是使用 Class 文件夹编写的,即所有方法都是文件夹 @myclassname 中的文件。我想读取 class 对象的成员。在正常的 classdef classes 中,声明一个 属性 public 可以解决问题。就我而言,我没有找到任何解决方案,我不想重写整个包。
解释我的问题的最小示例: 简单 class: \MatlabPath\@mytestclass\mytestclass.m
%myconstructor
function res =mytestclass()
st.a=1;
res=class(st,mfilename);
end
当前行为:
>> obj=mytestclass();
>> obj.a
Access to an object's fields is only permitted within its methods.
期望:
>> obj=mytestclass();
>> obj.a
ans =
1
谢谢
我知道您不想重写整个包,但如果 属性 访问很重要,您可能更喜欢它而不是实际的解决方案。
在第一个 MATLAB OOP classes 中,按照您的指示进行组织(所有方法都在一个文件夹中),程序员必须编写自己的 subsref
and subsasgn
方法,如果他们想要自定义访问他们的 class属性。
我必须说我确实玩过它,但很快就放弃了,因为构建简单的 classes 非常乏味。 MATLAB 可能注意到了这一点,并在后来的版本中引入了新的 Classdef
模型。尽管仍然有一些快速(由于 MATLAB 按值传递几乎所有内容),这个 Classdef
模型比旧公式更方便。
如果你想坚持使用旧模型,我可以给你一个极简主义的例子,它会给你想要的行为。如果您只对公开一些属性感兴趣,您可以复制几次。如果您打算公开包的所有属性,那么我向您保证,重写包比将我的解决方案应用于广泛的现有代码库更省力。
因此在您的文件夹中:\MatlabPath\@mytestclass\
,您现在需要两个文件:
mytestclass.m
(例如,我添加了几个不同的属性)
function res =mytestclass()
st.scalar = 1 ;
st.array = [1 2 3] ;
st.cellarray = {'1' '2' '3'} ;
res=class(st,mfilename);
end
和你自己的 subsref.m
:
function out = subsref(obj,S)
thisS = S(1) ;
if strcmp(thisS.type , '.')
out = obj.(thisS.subs) ;
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
end
% recursive call if the struct S has more than one element
if numel(S) > 1
S(1) = [] ;
out = subsref(out,S) ;
end
end
有了它,您现在可以访问您的属性:
>> obj.scalar
ans =
1
>> obj.array
ans =
1 2 3
>> obj.cellarray
ans =
'1' '2' '3'
这个最小的 subsref
也适用于对数组进行索引:
>> obj.array(2:end)
ans =
2 3
>> obj.cellarray(2)
ans =
'2'
它也适用于赋值:
>> obj.scalar = 125 ;
>> obj.scalar
ans =
125
>> obj.array(2:end) = [8 9] ;
>> obj.array
ans =
1 8 9
请记住,这是一个最小的示例,某些 属性 类型可能无法很好地响应这些简单的情况,在这种情况下,您将必须添加特定的代码来处理每个特定的情况。
但是如果你只想公开所有 class 成员,你可以将 subsref
函数简化为:
function out = subsref(obj,S)
out = builtin('subsref',obj,S);