如何在MATLAB 2013b中创建自定义setter方法?

时间:2013-09-09 23:45:56

标签: matlab oop getter-setter

参加以下课程

classdef MyClass
    properties (Access = public)
        MyProperty;
    end

    methods
        function this = MyClass()
            % initialize the class
            this.MyProperty = [];
            this.LoadProperty(2,2);
        end

        function p = GetProperty(this)
            p = this.MyProperty;
        end

        function this = LoadProperty(this, m, n)
            % loads the property
            this.MyProperty = zeros(m, n);
        end
    end
end

然后你打电话:

obj = MyClass();
obj.GetProperty()

它将返回[] - 这是在构造函数方法中分配给MyProperty的第一个值。

LoadProperty方法充当setter,但它没有设置任何内容。如何为MyProperty创建一个setter?我来自C#背景,非常简单。 - >已解决(见下文)

我怀疑这是引用和对象的问题,因为MATLAB总是将对象本身作为第一个参数发送到类的每个方法,而不是像C#那样仅发送引用。

提前谢谢!


修改

如果我将行this.LoadProperty(2,2);更改为this = this.LoadProperty(2,2);,则可行。

现在,有没有办法在MATLAB中创建一个void-return方法,它只设置一个类属性,就像在C#,C ++,Java等中通常所期望的一样?

2 个答案:

答案 0 :(得分:4)

将班级定义(第一行)更改为:

classdef MyClass < handle

这通过继承handle class将类定义为具有引用语义。文档解释了差异:

答案 1 :(得分:1)

您可以直接访问它,因为您已将其声明为public:

classObj = MyClass; 
classObj.MyProperty = 20;   
classObj.MyProperty % ans = 20

但似乎你想要封装它。有几种方法可以做到这一点。假设您拥有私有访问权限,如下所示。

classdef MyClass
    properties (Access = private)
        MyProperty;
    end

    methods
        function this = MyClass()
            % initialize the class
            this.MyProperty = [];
            this.LoadProperty(2,2);
        end

        function p = GetProperty(this)
            p = this.MyProperty;
        end

        function this = LoadProperty(this, m, n)
            % loads the property
            this.MyProperty = zeros(m, n);
        end
    end 
end

然后你可以添加一个set方法,如下所示(我通常使用小写的函数和变量,大写使用大写的类。如果你愿意,你可以将它改为大写):

function this = setProperty(this,value)
   this.MyProperty = value;
end

由于这不是句柄类,因此您需要使用以下函数:

myClass = myClass.setProperty(30); % You can also set it to [30 30 30; 20 20 20] if you want, there are no restrictions if you don't explicitly write into your function.

否则你可以使用句柄类:

classdef MyClass < handle

在这种情况下,您可以通过执行以下操作直接更改:

myClass.setProperty(40);

但这也意味着您对此类所做的任何引用都不会创建新对象,而是来自此对象的另一个句柄。也就是说,如果你这样做:

myClass2 = myClass;
% and uses myClass2.setProperty:
myClass2.setProperty(40)
myClass.GetProperty % ans = 40!

所以,如果你想避免这种行为(也就是说,当你将它传递给一个函数或另一个变量时,你需要一个类的副本,也就是按值调用)但是想要指定你的获取和设置方法应该是行为,Matlab为您提供了两个内置方法,您可以在分配属性时重载。那就是:

function out = get.MyProperty(this)
function set.MyProperty(this,value)

通过覆盖这些方法,您将覆盖用户调用

时发生的情况
myClass.MyProperty          % calls out = get.MyPropertyGet(this)
myClass.MyProperty = value; % calls set.MyProperty(this,value)

但是你也可以使用句柄类并在你的类中创建一个复制函数:

function thisCopy = copy(this)
   nObj = numel(this);
   thisCopy(nObj) = MyClass;
   meta = metaclass(MyClass);
   nProp = numel(meta,'PropertyList');
   for k = 1:nObj
     thisCopy(k) = MyClass; % Force object constructor call
     for curPropIdx=1:nProp
       curProp = meta.PropertyList(curPropIdx);
       if curProp.Dependent
         continue;
      end
      propName = curProp.Name;
      thisCopy(k).(propName) = this(k).(propName);
    end
  end
end

这应该在您的classdef中指定(就像您的get. set.方法一样)作为公共方法。如果您声明了此方法并希望class2成为class的副本,那么您确实喜欢这样:

myClass = MyClass;
myClass.setProperty(30);
myClass2 = copy(myClass);
myClass2.setProperty(40); %
myClass.GetProperty % ans = 30

它应该对你的MyClass来说有点复杂,因为它复制了你的类对象中的每个(非handle)属性,并且当你有一个类对象数组时工作。有关更多参考,请参阅@Amro's answermatlab oop documentation

这也解释了为什么this = this.LoadProperty有效,而this.LoadProperty(2,2)没有。