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

时间:2015-05-28 22:44:46

标签: matlab oop

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

我有A类,在A类的属性中,我想定义两个名为doctor_info和patient_info的结构。从OOP的角度来看,我应该使用A级医生和患者的医生和患者的对象,还是使用结构更好,不要定义班级患者和医生。如果定义医生和患者这两个类更好,那么A类的psudo代码是什么?

PS:我搜索了matlab的opp,堆栈交换以及网络,但无法找到我的答案。在堆栈交换中,我在C ++中找到了一个相关的问题,但答案并不能让我满意:How to define an object from Class A in Class B

非常感谢你的帮助

1 个答案:

答案 0 :(得分:0)

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

我喜欢structs因为我发现它们相对于自定义类非常轻,并且非常灵活,因为可以即时添加字段。 在涉及复杂的应用程序时会想到structs的一些缺点:

  • 字段是动态添加的:我知道我列为加号,但必须谨慎使用才能加分。 Matlab很乐意将拼写错误的字段'geuss'添加到包含struct guess的任务中,一切都会好的,直到它没有。自定义对象不会发生这种情况,因为只能通过继承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来创建所有这些医疗图表,但代价是在每个实例中复制所有医生的信息。 它在内存方面相当多余,但并不是一件大事。

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

我们可以通过创建继承自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的一部分从中删除。我不知道我认为这里有必要,但我想我会提到它。)