我试图使MATLAB比它更有用(对我而言),我一直想要解决的一个问题是更好的类构造函数。我想拥有以下界面:
MyClass.new(some_args).method1;
# instead of classical:
obj = MyClass(some_args);
obj.method1;
我可以通过定义静态方法new
:
classdef MyClass
methods
function obj = MyClass(varargin); end
function method1(obj,varargin); end
end
methods (Static)
function obj = new(varargin); obj = MyClass(varargin{:}); end
end
end
但是这需要在所有类中添加这样的方法,因此它不是非常优雅/方便。我认为我可以通过使用以下构造函数
定义一个公共类来绕过它classdef CommonClass
methods (Static)
function obj = new(varargin)
# getting name of the current file (Object), i.e. basename(__FILE__)
try clear E; E; catch E, [s, s] = fileparts(E.stack(1).file); end;
# creating object with name $s
obj = eval([s '(varargin{:})']);
end
end
end
classdef MyClass < CommonClass
end
但是,这不起作用,因为MATLAB从new()
调用Object.m
,因此我获得了Object
而不是MyClass
的实例。
我有什么想法可以改进它吗?
EDIT1:
我希望它也适用于在其他类中创建的类:
classdef MyAnotherClass < CommonClass
methods
function obj = MyAnotherClass
child = MyClass.new;
end
end
end
>> MyAnotherClass.new
答案 0 :(得分:2)
就个人而言,我没有看到按原样调用构造函数的问题,但如果您确实希望通过new
调用它,则下面的getStaticCallingClassName
可能对您有用。
以下是您使用它的方式:
classdef CommonClass
methods (Static)
function obj = new(varargin)
%# find out which class we have to create
className = getStaticCallingClassName;
constructor = str2func(sprintf('@%s'className));
%# creating object with name $s
obj = constructor(varargin{:});
end
end
end
classdef MyClass < CommonClass
end
有了这个,你可以打电话
obj = MyClass.new(input,arguments);
这里是getStaticCallingClassName
:
function className = getStaticCallingClassName
%GETSTATICCALLINGCLASSNAME finds the classname used when invoking an (inherited) static method.
%
% SYNOPSIS: className = getStaticCallingClassName
%
% INPUT none
%
% OUTPUT className: name of class that was used to invoke an (inherited) static method
%
% EXAMPLE
%
% Assume you define a static method in a superclass
% classdef super < handle
% methods (Static)
% doSomething
% % do something here
% end
% end
% end
%
% Also, you define two subclasses
% classdef sub1 < super
% end
%
% classdef sub2 < super
% end
%
% Both subclasses inherit the static method. However, you may be
% interested in knowing which subclass was used when calling the static
% method. If you call the subclass programmatically, you can easily pass
% the name of the subclass as an input argument, but you may want to be
% able to call the method from command line without any input and still
% know the class name.
% getStaticCallingClassName solves this problem. Calling it in the above
% static method 'doSomething', it returns 'sub1' if the static method was
% invoked as sub1.doSomething. It also works if you create an instance of
% the subclass first, and then invoke the static method from the object
% (e.g. sc = sub1; sc.doSomething returns 'sub1' if .doSomething calls
% getStaticCallingClassName)
%
% NOTE: getStaticCallingClassName reads the last workspace command from
% history. This is an undocumented feature. Thus,
% getStaticCallingClassName may not work in future releases.
%
% created with MATLAB ver.: 7.9.0.3470 (R2009b) on Mac OS X Version: 10.5.7 Build: 9J61
%
% created by: Jonas Dorn
% DATE: 16-Jun-2009
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% get the last entry of the command line from the command history
javaHistory=com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
lastCommand = javaHistory(end).toCharArray';%'# SO formatting
% find string before the last dot.
tmp = regexp(lastCommand,'(?:=|\.)?(\w+)\.\w+\(?(?:.*)[;,]*\s*$','tokens');
try
className = tmp{1}{1};
catch me
className = [];
end
% if you assign an object, and then call the static method from the
% instance, the above regexp returns the variable name. We can get the
% className through getting the class of xx.empty.
if ~isempty(className)
className = evalin('base',sprintf('class(%s.empty);',className));
end
答案 1 :(得分:0)
我可能会遗漏一些东西,但
出了什么问题method1(MyClass(some_args))
? (我一直使用这种模式。)