【问题标题】:How can I write generalized functions to manipulate private properties?如何编写通用函数来操作私有属性?
【发布时间】:2012-10-01 08:44:07
【问题描述】:

在 Matlab 中,我想对类的私有成员执行一些操作。我也想在其他课程上执行完全相同的任务。显而易见的解决方案是在一个单独的 M 文件中编写一个函数,所有类都调用该函数来执行此任务。然而,这在 Matlab 中似乎是不可能的(见下文)。有没有其他方法可以做到这一点?

具体问题如下:假设我有一个包含内容的 m 文件

classdef PrivateTest
    properties (Access=private)
        a
    end

    methods
        function this = directWrite(this, v)
            this.a = v;
        end
        function this = sameFileWrite(this, v)
            this = writePrivate(this, v);
        end
        function this = otherFileWrite(this, v)
            this = otherFileWritePrivate(this, v);
        end
        function print(this)
            disp(this.a);
        end
    end
end

function this = writePrivate(this, v)
    this.a = v;
end

...以及另一个包含内容的 m 文件

function this = otherFileWritePrivate(this, v)
    this.a = v;
end

在实例化p = PrivateTest 之后,这两个命令都可以正常工作(如预期的那样):

p = p.directWrite(1);
p = p.sameFileWrite(2);

...但是即使是相同的代码,这个命令也不起作用,只是在不同的 m 文件中:

p = p.otherFileWrite(3);

因此,似乎任何对类的私有属性执行操作的代码都必须与定义这些私有属性的 classdef 位于同一个 m 文件中。另一种可能性可能是让所有类都继承一个具有写入方法的类,但 Matlab 也不允许这样做。在一个 m 文件中,我会有以下代码:

classdef WriteableA
    methods
        function this = inheritWrite(this, v)
            this.a = v;
        end
    end
end

...在另一个 m 文件中,我会有这个代码:

classdef PrivateTestInherit < WriteableA
    properties (Access=private)
        a
    end
end

但是,在实例化 p = PrivateTestInherit; 之后,命令 p.inheritWrite(4) 会导致与之前相同的错误消息:“不允许设置 'PrivateTestInherit' 类的 'a' 属性。”

鉴于此,如何在 Matlab 中泛化操纵私有属性的代码,或者是否有可能?

【问题讨论】:

    标签: oop matlab properties private


    【解决方案1】:

    不能在类之外操作私有属性,这就是为什么它们被称为私有的。这个想法被称为封装。

    您可以通过多种方式解决它:

    1. 定义包装私有的公共属性,并更改它。 (见下面的代码)
    2. (继承模式)做一个普通的父类,你的其他类继承函数

    classdef PrivateTest
        properties (Access=private)
            a
        end
    
        properties(Access=public,Dependent)
            A
        end
    
        methods
            function this = set.A(this,val)
                this.a = val;
            end
    
            function val = get.A(this)
               val = this.a;
            end
    
            function this = directWrite(this, v)
                this.a = v;
            end
            function this = sameFileWrite(this, v)
                this = writePrivate(this, v);
            end
            function this = otherFileWrite(this, v)
                this = otherFileWritePrivate(this, v);
            end
            function print(this)
                disp(this.a);
            end
        end
    end
    
    function this = writePrivate(this, v)
        this.A = v;
    end
    

    【讨论】:

    • 对不起,我的方法命名混乱。 otherFileWritePrivate 函数是在名为“otherFileWritePrivate.m”的 m 文件中定义的唯一函数。从p = p.otherFileWrite(3); 生成的错误消息是“不允许设置'PrivateTest' 类的'a' 属性。”,而不是“未定义函数'otherFileWritePrivate' 用于'PrivateTest' 类型的输入参数。”
    • [以上评论不再适用] 我不想在课堂外操纵私有属性;调用外部m文件的是PrivateTest的方法。完全相同的代码在同一个 m 文件中时可以正常工作,但当我尝试遵循良好的编码实践通过将其放在单独的 m 文件中进行概括时它不起作用,多个类可以使用相同的代码。我想保持封装,所以选项 1 不好。我很确定选项 2 在 Matlab 中也是不可能的,但我会更新问题以包含我尝试过的内容。
    • @Ben,我想你会的。你在otherFileWritePrivate.m 中做this.a = v;。从 Matlab 的角度来看,您调用了外部函数,将对象传递给它,因此它只能更改其公共属性
    • 当然,这是根本问题——因为 Matlab 似乎将不同 m 文件中的代码视为类的外部代码,即使该代码是从类中调用的,如何编写通用代码来操作私有属性?
    • 此答案中将 A 作为公共依赖属性的代码只是将我的私有属性更改为公共属性。它不允许对私有属性的操作进行泛化。
    猜你喜欢
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多