Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop MATLAB的快速脏类构造函数?_Oop_Class_Matlab_Constructor - Fatal编程技术网

Oop MATLAB的快速脏类构造函数?

Oop MATLAB的快速脏类构造函数?,oop,class,matlab,constructor,Oop,Class,Matlab,Constructor,我试图让MATLAB比它(对我来说)更有用,我一直想解决的问题之一是更好的类构造函数。我希望有以下界面: MyClass.new(some_args).method1; # instead of classical: obj = MyClass(some_args); obj.method1; 我可以通过定义一个静态方法new轻松实现这一点: classdef MyClass methods function obj = MyClass(varargin); end fu

我试图让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

就个人而言,我不认为按原样调用构造函数有什么问题,但是如果您确实希望通过
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
下面是
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
function className=getStaticCallingClassName
%GETSTATICCALLINGCLASSNAME查找调用(继承的)静态方法时使用的类名。
%
%简介:className=getStaticCallingClassName
%
%输入无
%
%OUTPUT className:用于调用(继承的)静态方法的类的名称
%
%范例
%
%假设您在超类中定义了一个静态方法
%classdef超级
我可能遗漏了一些东西,但我怎么了

method1(MyClass(some_args))

?(我一直使用这种模式)。

你的方法很有趣,但它没有考虑到可以通过
new
在其他类中创建类:)我知道这不是MATLAB风格。我只是想在我的m脚本中至少尝一尝Ruby的味道。@Andrei Fokau:如果你调用
CommonClass.new
,那么你必须将
'MyClass'
作为参数传递给MATLAB,让MATLAB知道你想创建一个class
MyClass
的对象。但是,如果运行调用超类的静态方法
new
,则
getStaticCallingClassName
正是您所需要的。查看我的编辑。如果我尝试执行
MyAnotherClass.new
,它在构造函数中调用
MyClass.new
(请参阅我更新的问题),那么我将得到一个无限循环。有解决方案吗?@Andrei Fokau:理想情况下,
new
方法也接受类名作为可选输入。因此,如果您从代码中调用
new
,您可以硬编码应该构造哪个类。
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
method1(MyClass(some_args))