在MATLAB中,类的属性之一(在classdef
之后定义)是Sealed
,这意味着没有类可以将其用作超类(或者更准确地说,">表明这些类没有被设计为支持子类。1).
例如,如果我尝试实例化一个定义如下的类(考虑到table
是Sealed
):
classdef SomeLie < table
end
我会得到'MATLAB:class:sealed'
错误:
>> A = SomeLie;
Error using SomeLie
Class 'table' is Sealed and may not be used as a superclass.
由于我拒绝被机器告知我可以做什么或不可以做什么,无论如何,我想对Sealed
类进行子类。如何在 MATLAB R2017a 中做到这一点?
我很难相信这个系统是完全密封的,所以我正在寻找一种解决方案,导致Sealed
属性被默默忽略(或类似的东西)。所需的解决方案应该无需修改任何"库类定义"即可从中删除Sealed
。
我试着玩弄"反射",但到了死胡同......
classdef SomeLie % < table
properties (Access = private)
innerTable table;
end
properties (GetAccess = public)
methodHandles struct = struct();
end
methods
function slObj = SomeLie(varargin)
slObj.innerTable = table(varargin{:});
% methodHandles = methods(slObj.innerTable);
ml = ?table; ml = {ml.MethodList.Name}.';
ml = setdiff(ml,'end');
tmpStruct = struct;
for indM = 1:numel(ml)
tmpStruct.(ml{indM}) = str2func([...
'@(varargin)' ml{indM} '(slObj.innerTable,varargin{:})']);
end
slObj.methodHandles = tmpStruct;
end
function varargout = subsref(slObj,varargin)
S = struct(slObj);
varargout{:} = S.methodHandles.(varargin{1}.subs)(varargin{:});
end
end
end
(没有必要修复上面的代码,我只是在分享)
我不认为机器是问题所在,但类设计师和他当然有很好的动机来密封类。 编码的"哲学",一部分,你可以在包装类中"拥有"类,而无需定义它密封。
例如,假设类Hello是密封的,并且有一个方法(或函数,如果你愿意的话)sayHello,你想在继承的类中使用,你可以定义一个类FreeHello(公共),它包含一个Hello的实例。在构造函数中,您构建相应的 Hello,然后定义一个 sayHello 方法,该方法的主体只是调用您的 Hello 实例并使其执行 sayHello 方法(并相应地返回输出)。
为了"打开"密封类,你需要对所有属性和公共方法执行这些操作;当然,你仍然无法访问私有方法,但现在你可以根据需要对包装类进行子类化。