Matlab不允许定义不同的方法来定义具有不同参数列表的多个构造函数,例如这不起作用:
classdef MyClass
methods
function [this] = MyClass()
% public constructor
...
end
end
methods (Access = private)
function [this] = MyClass(i)
% private constructor
...
end
end
end
但是,如上例所示,有一些私有构造函数有时很有用,这些构造函数具有无法从公共接口调用的特定语法。
如果您需要定义公共和私有构造函数,您将如何最好地处理这种情况?
检查调用堆栈???
classdef MyClass
methods
function [this] = MyClass(i)
if (nargin == 0)
% public constructor
...
else
% private constructor
checkCalledFromMyClass();
...
end
end
end
methods(Static=true, Access=Private)
function [] = checkCalledFromMyClass()
... here throw an error if the call stack does not contain reference to `MyClass` methods ...
end
end
end
定义帮助程序基类???
% Helper class
classdef MyClassBase
methods (Access = ?MyClass)
function MyClassBase(i)
end
end
end
% Real class
classdef MyClass < MyClassBase
methods
function [this] = MyClass()
this = this@MyClassBase();
end
end
methods (Static)
function [obj] = BuildSpecial()
obj = MyClassBase(42); %%% NB: Here returned object is not of the correct type :( ...
end
end
end
其他解决方案???
答案 0 :(得分:2)
通过利用varargin
:
classdef MyClass
methods (Access = public)
function obj = MyClass(varargin)
% Do whatever you want with varargin
end
end
end
您可能更常见的是,所有语法都需要一些输入,然后还有一些可选输入:
classdef MyClass
methods (Access = public)
function obj = MyClass(reqInput1, reqInput2, varargin)
% Do whatever you want with varargin
end
end
end
如果你想对事物的构造方式有更多的控制,我会有一个构造函数,然后还有一些调用构造函数的公共静态方法。
例如,让我们说我希望能够通过直接提供参数或通过提供包含参数的配置文件的名称来构造对象:
classdef MyClass
methods (Access = public)
function obj = MyClass(reqInput1, reqInput2, varargin)
% Do whatever you want with varargin
end
end
methods (Static, Access = public)
function obj = fromFile(filename)
myparams = readmyconfigfile(filename);
obj = MyClass(myparams.reqInput1, myparams.reqInput2, ...);
end
end
end
然后,您可以使用o = MyClass(inputs)
或o = MyClass.fromFile(filename)
创建对象。
如果您想允许人们从配置文件中构造 ,那么您可以将构造函数设为私有。如果你想以其他方式调用构造函数,你可以添加额外的公共静态方法。
在任何情况下,重点是拥有一个接受多种语法的构造函数的惯用方法是利用varargin
。
答案 1 :(得分:2)
我曾经尝试解决此限制的一个偷偷摸摸的技巧是使用另一个只能由MyClass
构造的'tag'类,然后使用它来计算出你需要的构造函数变体。这是一个简单的草图:
classdef MyClass
properties
Info
end
methods
function o = MyClass(varargin)
if nargin == 2 && ...
isa(varargin{1}, 'MyTag') && ...
isnumeric(varargin{2}) && ...
isscalar(varargin{2})
o.Info = sprintf('Private constructor tag: %d', varargin{2});
else
o.Info = sprintf('Public constructor with %d args.', nargin);
end
end
end
methods (Static)
function o = build()
% Call the 'private' constructor
o = MyClass(MyTag(), 3);
end
end
end
和
classdef MyTag
methods (Access = ?MyClass)
function o = MyTag()
end
end
end
请注意Access = ?MyClass
说明符,这意味着只有MyClass
才能构建MyTag
的实例。还有更多关于在doc:http://www.mathworks.com/help/matlab/matlab_oop/method-attributes.html
答案 2 :(得分:1)
我很想在你的第一个选项上进行修改,但要修改构造函数以获得一个未记录的&#34;模式&#34;而不仅仅是任何输入arg。
在下面的示例中,我提供了该名称**private**
,但您可以拥有任何您希望最终用户不会偶然发现的内容......
要加倍确定你仍然可以检查堆栈。
function [this] = MyClass(i)
if (nargin == 0)
% public constructor
else
% private constructor
if ischar ( i ) && strcmp ( i, '**private**' )
this.checkCalledFromMyClass();
else
error ( 'MyClass:Consturctor', 'Error calling MyClass' );
end
end
end
end