简体   繁体   English

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

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

I have following class definition under +mypackage\\MyClass.m我在 +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

I use with_five() as a static factory method.我使用 with_five() 作为静态工厂方法。
Following script should create two objects.以下脚本应创建两个对象。

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

class_test1 has been created. class_test1 已创建。
For class_test2 it says:对于 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();

When I put MyClass.m outside of a package folder and remove the "import" statement, it works.当我将 MyClass.m 放在包文件夹之外并删除“import”语句时,它可以工作。
What am I doing wrong?我究竟做错了什么?

There are several wonky things in MATLAB with packages and with static methods. MATLAB 中有一些带有包和静态方法的奇怪的东西。

First, functions within a package must use the package name to reference other functions or classes within the same package (see here ).首先,包内的函数必须使用包名来引用同一包内的其他函数或类(请参阅此处)。 So the static method mypackage.MyClass.with_five() must be declared as follows:所以静态方法mypackage.MyClass.with_five()必须声明如下:

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

Without this, I see:没有这个,我看到:

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

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

Second, static class methods (at least the ones for classes inside packages) are not loaded until an object of the class is created.其次,静态类方法(至少是包内类的方法)在类的对象被创建之前不会被加载。 So we need to call the class constructor first:所以我们需要先调用类构造函数:

>> 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

The same is true if we import the class:如果我们导入类也是如此:

>> 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

This second point was true in R2017a (where the outputs above were generated), but is no longer true in R2021a.第二点在 R2017a(生成上述输出的地方)中是正确的,但在 R2021a 中不再正确。 I don't know in which release of MATLAB this was fixed, but in R2021a it is no longer necessary to create an object of a class to use its static method.我不知道这是在哪个 MATLAB 版本中修复的,但在 R2021a 中,不再需要创建类的对象来使用其静态方法。

I think what you are missing is the fact that when you import a static method, you have to import the class name and the method name ( https://au.mathworks.com/help/matlab/matlab_oop/importing-classes.html )我认为您缺少的是,当您导入静态方法时,您必须导入类名和方法名https://au.mathworks.com/help/matlab/matlab_oop/importing-classes.html )

This works:这有效:

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

Then do the following:然后执行以下操作:

>> import MyClass.with_five
>> x = with_five

Output:输出:

x = 

  MyClass with properties:

    num: 5

That being said: don't create an object in a member function of its own class!话虽如此:不要在它自己的类的成员函数中创建一个对象! As you suggest, a better choice is to move the factory to a different class.正如您所建议的,更好的选择是将工厂转移到不同的班级。 If you wanted to make a bunch of chainsaws, you would never go about trying to design a chainsaw that has a button on it that builds chainsaws.如果你想制作一堆链锯,你永远不会试图设计一个上面有一个按钮来构建链锯的链锯。 You would rather design a factory that can produce chainsaws that are designed to cut down trees.您宁愿设计一家可以生产用于砍伐树木的链锯的工厂。

A 'static factory' is not a bad thing. “静态工厂”并不是一件坏事。 This is actually a pretty common pattern especially in C#.这实际上是一种非常常见的模式,尤其是在 C# 中。 However, the factory is always its own class.但是,工厂始终是它自己的类。 Calling that method from another object that inherits from or extends that class (which I'm not sure you can even do in Matlab...) would most certainly be confusing if not deadly.从继承或扩展该类的另一个对象调用该方法(我不确定你甚至可以在 Matlab 中做到这一点......)如果不是致命的,肯定会令人困惑。 I also can't think of any reason you would ever need to do this.我也想不出你需要这样做的任何理由。 In fact I don't understand why with_five() should be static at all事实上我不明白为什么with_five()应该是静态的

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

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