2

参加以下课程

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?我来自 C# 背景,非常简单。-> 已解决(见下文)

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

先感谢您!


编辑:

如果我将行更改this.LoadProperty(2,2);this = this.LoadProperty(2,2);,它可以工作。

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

4

2 回答 2

4

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

classdef MyClass < handle

handle这通过从类继承来定义类具有引用语义。该文档解释了差异:

于 2013-09-10T01:10:01.823 回答
2

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

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!

所以,如果你想避免这种行为(也就是说,当你将它传递给一个函数或另一个变量时,你想要一个类的副本,也就是按值调用)但想指定你的 get 和 set 方法应该如何行为,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 的回答matlab oop 文档

这也是为什么this = this.LoadProperty有效而this.LoadProperty(2,2)无效的解释。

于 2013-09-10T01:26:28.890 回答