在matlab的B类属性中使用A类的对象?

Posted

技术标签:

【中文标题】在matlab的B类属性中使用A类的对象?【英文标题】:using an object from class A in properties of class B in matlab? 【发布时间】:2015-05-28 22:44:46 【问题描述】:

我是面向对象编程的新手,我想使用 MATLAB OOP 在 MATLAB 中编写代码。我有一个基本问题:我在 MATLAB 的 OOP pdf (https://www.mathworks.com/help/pdf_doc/matlab/matlab_oop.pdf) 中读到,使用类作为结构化数据比使用 MATLAB 结构更好。我现在的问题是:

我有 A 类,在 A 类的属性中,我想定义两个结构,命名为医生信息和患者信息。从 OOP 的角度来看,我应该在 A 类的属性中使用医生和病人类的对象,还是使用结构而不定义病人和医生类更好。如果最好定义两个类医生和病人,那么 A 类的伪代码是什么?

PS.:我在 matlab opp、stack exchange 和网络上搜索了很多,但找不到我的答案。在堆栈交换中,我在 C++ 中找到了一个相关问题,但答案并不让我满意:How to define an object from Class A in Class B

非常感谢您的帮助

【问题讨论】:

【参考方案1】:

从 Matlab OOP 的角度来看,struct 或自定义类的选择很大程度上取决于特定应用程序以及可维护性、可扩展性、性能等方面的考虑。

我喜欢structs,因为我发现它们相对于自定义类而言重量极轻,而且非常灵活,因为可以即时添加字段。 structs 对于复杂应用程序的一些缺点:

动态添加字段:我知道我列为加号,但必须小心使用它。 Matlab 很乐意在分配时将拼写错误的字段“geuss”添加到包含guessstruct,一切都会好起来的,直到它不是。自定义对象不会发生这种情况,因为只能通过从 dynamicprops 继承并显式调用 addprop 来动态添加属性(我认为)。

所有字段都是可见的,并且可以分配给所有人和所有内容。如果应用程序是为不太熟练的用户设计的,隐藏某些信息或限制/约束赋值变量或值可能会有所帮助或可能需要。

struct 中的字段在创建字段后无法对struct 的数据进行操作;在我看来,这是 OOP 成为主要编程范式之一的主要原因之一:拥有可以存储数据并让它返回结果而不关心如何计算的东西(对象)可能非常有用(如只要是正确的)。

但是,由于所有添加的自定义类都提供了强大的功能,因此也存在开销。 Matlab 的 OOP 模型的性能正在提高,但我认为 struct 作为一个简单的数据容器仍然具有原始性能。 如果你不需要电源,你可以毫无问题地避免它。


使用自定义类可以获得的另一件大事是可以跨实例自动更新信息的引用。为了说明这一点并希望间接解决您的第二个问题,请考虑以下MedicalChart

classdef MedicalChart < handle

    properties
        doctor_info  = [];
        patient_info = [];
    end 

    methods
        function MC = MedicalChart(doc,pat)
            if (nargin ~= 0)
                MC.doctor_info = doc;
                MC.patient_info = pat;
            end
        end
    end

end

我可以使用两个结构定义属性并创建该类的实例:

>> doctor.name  = 'Joe'     ;
>> doctor.phone = '555-0100';
>> patient.name = 'Bob'     ;
>> mc = MedicalChart(doctor,patient);
>> mc.doctor_info.phone
ans =
555-0100

但现在我可能有一个问题。假设我有一个大型应用程序,Joe 博士有很多患者,每个患者都有自己的MedicalChart 实例。 struct doctor 可以重复使用以创建所有这些医疗图表,但代价是在每个实例中复制所有医生的信息。 它在内存方面相当多余,但不是很大。

但是如果乔博士改变了他的号码怎么办? 我们必须使用更新的struct 重新创建所有MedicalCharts

我们可以通过创建继承自handleDoctor 类的Dr. Joe 实例来避免重新创建所有实例以及重复数据:

classdef Doctor < handle

    properties
        name
        phone
    end

    methods
        function doc = Doctor(name,phone)
            if (nargin ~= 0)
                doc.name  = name;
                doc.phone = phone;
            end
        end
    end

end

现在我们像这样创建MedicalChart

>> DrJoe = Doctor('Joe','555-0100');
>> patient.name = 'Bob';
>> mc = MedicalChart(DrJoe,patient);
>> mc.doctor_info.phone
ans =
555-0100

非常相似。但由于我继承自handle,因此内存中一次只有一个DrJoe 的实例。 因此,对该对象所做的任何更改都可以在 mc 中自动访问:

>> DrJoe.phone = '555-0111';
>> mc.doctor_info.phone
ans =
555-0111

这是一个非常好的功能,可以做很多类似数据库的事情,而 structs 根本无法做到。

唯一想到的复杂情况是当您删除实例时以及删除时它们的引用会发生什么。 在我的 R2014b 安装中,删除 DrJoe 可以正常工作,因为 mc 创建了 DrJoe 的本地副本。 实际上,患者不应该有医生,但考虑到这一点会使示例复杂化。

(我认为为了让一切正常工作,需要Doctor 跟踪它所在的MedicalCharts,并将其作为destructor 的一部分从它们中删除。我认为不需要在这里,但我想我会提到它。)

【讨论】:

以上是关于在matlab的B类属性中使用A类的对象?的主要内容,如果未能解决你的问题,请参考以下文章

python面向对象-2深入类的属性

oc学习之对象作为类的属性

Python-面向对象(组合封装与多态)

在 Matlab 中将结构属性的字段作为类的属性

Python_类的属性

前端技术之:如何通过类的属性获取类名