我试图找出创建 C++ 模板或 Java 通用对象替代方案的最佳方法。过去,由于多种不同的原因,我曾多次想这样做,但是现在我想做的是为几个相关类创建 saveobj 和 loadobj 函数。这个想法是我想要有一组通用的例程来创建一个默认的结构,然后进一步操纵它以获得我想要的结构。
我不能简单地使用外部函数,因为我需要访问对象的所有公共(public)(不是问题)和 protected (问题)非 transient 属性才能创建 loadobj 和 saveobj。
然后我考虑使用抽象接口(interface)。然而,使用抽象接口(interface)给我带来了同样的问题;相同,复制粘贴的代码漂浮在我的所有目标文件中。于是我想到了使用某种结合多重继承的成熟对象(我的大多数对象已经从接口(interface)的基本结构继承了)。我认为使用父类(super class)可以让我公开子类 protected 属性,但它似乎并没有那样工作。有什么建议么?
这是保存 obj 方法的多重继承方法的示例(迄今为止我拥有的最接近的方法)。
序列化程序.m
% Serializer.m
classdef Serializer
methods
function [saveObj] = saveobj( obj )
% Get metadata about the Object
meta = metaclass( obj );
meta = meta.PropertyList;
for p = meta'
if p.Transient | p.Dependent
continue; % Only serialize the correct fields
end
saveobj.(p.Name) = { obj.(p.Name) }; % Serialize
end % for ( property )
end % function ( saveobj )
end % methods
end % classdef ( Serializer )
TestSerializerA.m
% TestSerializerA.m
classdef TestSerializerA < Serializer
properties
PropA = 'a';
end % properties ( public )
properties( Access = protected )
HiddenA = 'ha'
end % properties ( protected )
end % classdef ( TestSerializerA )
TestSerializerB.m
% TestSerializerB.m
classdef TestSerializerB < TestSerializerA & Serializer
properties
PropB = 'b'
end
properties( Access = protected )
HiddenB = 'hb';
end % properties ( protected )
end % classdef ( TestSerializerB )
最佳答案
解决方案
您可以使用 Access lists 完成您想要做的事情。您可以允许 Serializer
类访问您想要序列化的任何 protected /私有(private)类成员。这允许每个类自行确定其哪些成员被序列化。由于您允许访问 Serializer
,因此您不想继承它。如果这样做,层次结构中的所有类都可以访问这些成员。这是重写的 Serializer
类:
classdef Serializer
methods
function SerializedObj = serialize(~, Obj)
% Get metadata about the Object
meta = metaclass(Obj);
meta = meta.PropertyList;
for p = meta' %'
if p.Transient || p.Dependent
continue; % Only serialize the correct fields
end
try
SerializedObj.(p.Name) = { Obj.(p.Name) }; % Serialize
catch Me
% the class has chosen not to allow this property to be
% serialized. decide how to handle it.
if ~strcmp(Me.identifier, 'MATLAB:class:GetProhibited')
Me.rethrow()
end
end
end
end
end
end
请注意,您可以决定如何处理访问限制。在上面的例子中,我什么都不做。但是您可以发出警告,抛出错误等...。
现在,不是从
Serializer
继承,而是创建一个抽象的 Serializable
类,它将启用序列化。classdef (Abstract) Serializable
properties (Access = private)
Serializer_ = Serializer()
end
methods
function savedObj = saveobj(This)
savedObj = This.Serializer_.serialize(This);
end
end
end
现在,您希望启用序列化的任何类都将额外继承自
Serializable
。您可以指定 Serializer
可以访问哪些 protected /私有(private)成员。例子
以下类具有两个可序列化属性和一个隐藏(不可序列化)属性。
classdef TestSerializerA < Serializable
properties
PropA = 'a';
end
properties( Access = {?TestSerializerA, ?Serializer} )
% This property is protected and serializable
SerializableA = 'sa'
end
properties (Access = private)
% This property is private and not serializable
HiddenA = 'ha';
end
end
这是 MATLAB 的结果:
>> Test = TestSerializerA
Test =
TestSerializerA with properties:
PropA: 'a'
>> b = saveobj(Test)
b =
PropA: {'a'}
SerializableA: {'sa'}
下一个示例继承自
TestSerializerA
,并具有额外的两个可序列化属性和一个隐藏属性。classdef TestSerializerB < TestSerializerA & Serializable
properties
PropB = 'b';
end
properties (Access = {?TestSerializerB, ?Serializer})
% This property is protected and serializable.
SerializableB = 'sb';
end
properties (Access = protected)
% This property is protected and not serializable.
HiddenPropB = 'hb';
end
end
请注意,从
Serializable
重新继承是不必要的,但会使代码更易于阅读。最后,MATLAB 的结果:
>> Test = TestSerializerB
Test =
TestSerializerB with properties:
PropB: 'b'
PropA: 'a'
>> b = saveobj(Test)
b =
PropB: {'b'}
SerializableB: {'sb'}
PropA: {'a'}
SerializableA: {'sa'}
我希望这有帮助!
关于matlab - 在 MATLAB 中模拟 C++ 模板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17242291/