在Matlab中,我想使用静态方法创建一个替代构造函数,并且我希望这个构造函数能够继承到子类。我没有这样做,因为我无法在静态方法中获取对 calling 类的引用。
考虑这个带有超类 A 的示例代码,它有一个替代构造函数
fromSomething
:
classdef A
properties
a
end
methods
function obj = A(a)
if nargin
obj.a = a;
end
end
end
methods(Static)
function obj = fromSomething()
obj = A(42);
end
end
end
可以通过调用
A
创建 A.fromSomething()
的实例。
现在考虑子类 B:
classdef B < A
methods
function someFunctionality(obj)
end
end
end
调用
B.fromSomething()
会给出 A
类型的对象。这不是理想的行为。如何更改此代码,以便 B.fromSomething()
为我提供 B
类型的对象,并尽可能减少代码重用?
在 Python 中,这可以使用
@classmethod
装饰器来完成。
from dataclasses import dataclass
@dataclass
class A:
a : float
@classmethod
def from_something(cls):
return cls(42)
class B(A):
def some_functionality(self):
...
请注意,在 Python 代码中
B.from_something()
将返回类型为 B
的对象。
我尝试使用
dbstack
获取当前类的类名:
...
function obj = fromSomething()
cls = currentClass();
obj = feval(cls.Name, 42);
end
...
function [ cls, str ] = currentClass( )
% Taken from https://nl.mathworks.com/matlabcentral/answers/77387-any-way-to-get-the-current-class
dbk = dbstack( 1, '-completenames' );
if isempty( dbk )
str = 'base';
else
str = dbk(1).name;
end
cac = regexp( str, '\.', 'split' );
switch numel( cac )
case 1
case 2
cls = meta.class.fromName( cac{1} );
str = cac{2};
case 3
otherwise
end
end
但是,dbstack 返回该函数定义所在的类(在本例中:
A
),而不是函数调用所在的类(在本例中,调用B
时为B.fromSomething()
) 。结果 B.fromSomething()
仍然会返回 A
类型的对象。
@classmethod
是一个非常Pythony的东西,你需要它是因为Python不做函数重载,并且不便于模拟它。在 MATLAB 中,函数具有多个签名并根据给定的输入执行不同的操作是很常见的。
我认为,您的用例是在给定特定输入
something
的情况下构造一个对象:A.fromSomething(something)
,而不是普通的A()
或A.fromFoo(foo)
。
在 MATLAB 中,所有这些情况通常由同一个构造函数处理。你可以让它看起来像这样:
classdef A
% ...
methods
function obj = A(arg)
if nargin == 0
% case A()
else
if isa(arg, 'Something')
% case A(something)
elseif isa(arg, 'Foo')
% case A(foo)
else
error('Illegal input')
end
end
end
end
end
我想说,从文档中阅读,MATLAB 似乎没有类方法:
https://uk.mathworks.com/help/matlab/matlab_oop/how-to-use-methods.html
事实上,这在大多数编程语言中并不是常见的方法类型。