繁体   English   中英

如何在matlab包中使用静态工厂方法?

[英]How do I use static factory method in matlab package?

我在 +mypackage\\MyClass.m 下有以下类定义

classdef MyClass  
    properties
        num
    end
    
    methods (Static)
        function obj = with_five()
            obj = MyClass(5);
        end
    end
    
    methods
        function obj = MyClass(num)
            obj.num = num;
        end
    end
end

我使用 with_five() 作为静态工厂方法。
以下脚本应创建两个对象。

import mypackage.MyClass
class_test1 = MyClass(5);
class_test2 = MyClass.with_five();

class_test1 已创建。
对于 class_test2 它说:

Error using MyClass.with_five
Method 'with_five' is not defined for class 'MyClass' or is removed from MATLAB's search path.
Error in Testpackage (line 4)
class_test2 = MyClass.with_five();

当我将 MyClass.m 放在包文件夹之外并删除“import”语句时,它可以工作。
我究竟做错了什么?

MATLAB 中有一些带有包和静态方法的奇怪的东西。

首先,包内的函数必须使用包名来引用同一包内的其他函数或类(请参阅此处)。 所以静态方法mypackage.MyClass.with_five()必须声明如下:

    methods (Static)
        function obj = with_five()
            obj = mypackage.MyClass(5);
        end
    end

没有这个,我看到:

>> mypackage.MyClass.with_five
Undefined function or variable 'MyClass'.

Error in mypackage.MyClass.with_five (line 8)
            obj = MyClass(5);

其次,静态类方法(至少是包内类的方法)在类的对象被创建之前不会被加载。 所以我们需要先调用类构造函数:

>> clear classes
>> mypackage.MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
 
>> mypackage.MyClass(1);
>> mypackage.MyClass.with_five

ans = 

  MyClass with properties:

    num: 5

如果我们导入类也是如此:

>> clear classes
>> import mypackage.MyClass
>> MyClass.with_five
Undefined variable "mypackage" or class "mypackage.MyClass.with_five".
 
>> MyClass(3);
>> MyClass.with_five

ans = 

  MyClass with properties:

    num: 5

第二点在 R2017a(生成上述输出的地方)中是正确的,但在 R2021a 中不再正确。 我不知道这是在哪个 MATLAB 版本中修复的,但在 R2021a 中,不再需要创建类的对象来使用其静态方法。

我认为您缺少的是,当您导入静态方法时,您必须导入类名和方法名https://au.mathworks.com/help/matlab/matlab_oop/importing-classes.html )

这有效:

classdef MyClass  
    properties
        num
    end
    
    methods (Static)
        function obj = with_five()
            obj = MyClass(5);
        end
    end
    
    methods
        function obj = MyClass(num)
            obj.num = num;
        end
    end
end

然后执行以下操作:

>> import MyClass.with_five
>> x = with_five

输出:

x = 

  MyClass with properties:

    num: 5

话虽如此:不要在它自己的类的成员函数中创建一个对象! 正如您所建议的,更好的选择是将工厂转移到不同的班级。 如果你想制作一堆链锯,你永远不会试图设计一个上面有一个按钮来构建链锯的链锯。 您宁愿设计一家可以生产用于砍伐树木的链锯的工厂。

“静态工厂”并不是一件坏事。 这实际上是一种非常常见的模式,尤其是在 C# 中。 但是,工厂始终是它自己的类。 从继承或扩展该类的另一个对象调用该方法(我不确定你甚至可以在 Matlab 中做到这一点......)如果不是致命的,肯定会令人困惑。 我也想不出你需要这样做的任何理由。 事实上我不明白为什么with_five()应该是静态的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM