第6章LabVIEW面向对象程序设计课件.ppt
LabVIEW面向对象程序设计,Intelligent Electronics InstituteHuazhong University of Science & Technology,2,目录,面向对象LabVIEW与面向对象程序设计LabVIEW对象基本实现LabVIEW对象高级技巧实例介绍提示与建议习题,3,6.1面向对象,对象与类的概念对象是系统中用来描述客观事物的一个实体,是构成系统的基本单位,由属性和对这些属性进行的操作等构成;类是对象的抽象及描述,是具有共同属性和操作的多个对象的统一描述体,类也是对象,是一种集合对象;在类的描述中,每个类要有一个名字,要表示一组对象的共同特征,还必须给出一个生成对象的实例的具体方法;类中的每个对象都是该类的对象实例,系统运行时通过类定义属性初始化可以生成该类的对象实例。,6.1面向对象,属性与方法的概念对象是属性及方法的封装体;对象的属性是指描述对象的数据,这些数据可以是系统或用户定义的数据类型,也可以是一个对象的数据类型;对象的方法是指定义在对象属性上的一组操作的集合;方法是为响应消息而完成的算法,表示对象内部实现的细节,对象方法集合体现了对象的行为能力;对象的属性和方法是对象定义的组成要素,它们统称为对象的特征。,4,6.1面向对象,面向对象中的三要素:在面向对象的程序设计中,封装就是把相关的数据和代码结合成一个有机的整体,形成数据和操作代码的封装体,对外只提供一个可以控制的接口,内部大部分的实现细节对外隐蔽,达到对数据访问权的合理控制;在面向对象程序设计中,继承表达的是类之间的关系,这种关系使得一个类可以继承另一类的属性和方法,从而提供了通过现有的类创建新类的方法,也提高了软件复用的程度;多态是面向对象程序设计的重要特性之一,是指不同的对象收到相同的消息时产生不同的操作行为,或者说同一个消息可以根据发送消息的对象的不同而采用多种不同的操作行为。,5,封装,继承,多态,6.2LabVIEW与面向对象程序设计,LabVIEW引入面向对象编程时的术语LabVIEW依然使用家族关系术语:父与子、兄弟与堂兄弟等,这些都是用户已经熟悉的术语,当提到某个类的父类时,都可以理解这两个类之间的关系;LabVIEW类成员的限定性术语:依然采用“私有的”、“共有的”和“受保护的”等词汇。,6,6.2LabVIEW与面向对象程序设计,继承LabVIEW在实现继承特性时坚持这样一条原则:LabVIEW用户能够实现类的继承,可以选择一个已有类作为父类,创建一个子类,并且可以覆盖父类中的方法;LabVIEW提供了(Object)类,作为所有LabVIEW类的祖先;LabVIEW目前只支持公共继承,而不支持私有继承和多继承。,7,6.2LabVIEW与面向对象程序设计,封装LabVIEW实现了类的封装,但对封装特征进行了选择;LabVIEW类只包含对私有数据的支持,不提供公共数据和受保护的数据两种属性;LabVIEW类中的方法,不仅可以是私有的,还可以是公共的或受保护的。,8,6.2LabVIEW与面向对象程序设计,多态多态性表现有两种,即编译时的多态性和运行时的多态性。编译时的多态性是用函数的重载来实现的,运行时的多态性是用虚函数来实现的,而这两种方式在LabVIEW的类中都没有实现。首先,LabVIEW类不支持重载,但这种多态性的思想在LabVIEW的早期版本中就一直存在并发挥着重要作用,主要表现为多态的函数、VI和单位;其次,对于虚函数而言,“虚拟”和“虚拟分配”的概念在LabVIEW中也面临一些问题,LabVIEW面向对象编程选择了“动态”和“动态分配”来代替这两个术语。,9,6.3LabVIEW对象基本实现,创建类通过菜单“FileNewClass”或者在项目浏览器的右键快捷菜单中选择“NewClass”项,都可以创建LabVIEW类;创建类时,LabVIEW将创建一个新的类库文件(.lvclass),该文件可以记录类的私有数据控件(Private Data Control)和所有被创建的成员VI的信息,包括VI列表及VI的属性等;类的数据被定义在私有数据控件中,私有数据控件是一个数据簇,与类库文件是一一对应的,并保存在类库文件中,私有数据控件的名称以“.ctl”作为扩展名。,10,6.3LabVIEW对象基本实现,私有数据控件示例,11,类库文件中的私有数据控件,6.3LabVIEW对象基本实现,编辑私有数据成员在项目浏览器窗口双击类的私有数据控件,可以对类中的数据成员进行编辑,将需要的控件放置到该类的定义私有数据控件中,作为类私有数据簇中的成员。,12,私有数据成员,6.3LabVIEW对象基本实现,设置继承在LabVIEW中,通过“继承”可在现有类的基础上创建一个新类;当一个新类被设置为继承另一个LabVIEW类时,这个新类就可以使用它所继承的类中“公共”及“保护”型的成员VI;在LabVIEW中,所有的类都默认继承LabVIEW Object的基本类。,13,6.3LabVIEW对象基本实现,设置继承示例,14,默认继承关系,6.3LabVIEW对象基本实现,改变类的继承关系在类名称上右击,进入属性设置对话框,选择“继承”(Inheritance),然后单击“更改继承”(Change Inheritance),可改变类的继承关系。,15,更改后的继承关系,6.3LabVIEW对象基本实现,创建方法在类名称上右击,选择需要创建VI的类型:普通成员VI、动态成员VI或重写VI(Override VI)。,16,6.3LabVIEW对象基本实现,新建静态成员VI新建静态成员VI后,会打开一个空面板的VI,用户可以根据应用需要添加程序代码;静态方法只有单个VI,在子类中无法创建与父类静态成员VI相同名称的成员VI。,17,6.3LabVIEW对象基本实现,新建动态成员VI新建动态成员VI后,会打开一个含有部分代码的VI,其中包括错误输入簇、错误输出簇、用于错误处理的条件结构,以及输入LabVIEW类和输出LabVIEW类;动态成员VI主要出现在具有继承关系的LabVIEW类中,只有当子类需要继承并重写父类中的某些VI时,这些VI才有必要设置为动态成员VI。,18,“大四学生”类中获取成绩的程序框图,6.3LabVIEW对象基本实现,创建重写成员VI重写成员VI是对祖先类中动态VI的重写,必须与祖先类中的同名成员VI具有相同的重入设置、首选执行设置、优先级设置、连线板接线端、连线板模式和访问范围;创建重写成员VI时,LabVIEW会自动调用父类方法的节点、动态输入和输出类接线端及其他匹配祖先类VI所需的接线端并放置在程序框图中;当选择创建时若不存在可重写的祖先类成员VI,LabVIEW将禁用重写成员VI的选项。,19,6.3LabVIEW对象基本实现,右击“保研生”类,选择“新建”下拉列中的“用于重写的VI”,会出现一个提示框用于选择需要重写的动态VI。我们选择“大四学生”类下的“获取成绩.vi”,LabVIEW会自动生成一个“保研生”类下的“获取成绩.vi”。,20,“保研生”类中获取成绩的程序框图,6.3LabVIEW对象基本实现,输入或输出接线端对于动态VI,右键单击连线板上的输入或输出接线端,会发现其连接为动态分配模式。,21,“保研生”类中获取成绩的输入端口,6.3LabVIEW对象基本实现,动态分派程序在编写程序时,动态成员VI在程序背面板上就像一般的子VI一样,不过当运行时,输入端口传递进来的数据就决定了调用哪个类中的成员VI。,22,6.3LabVIEW对象基本实现,访问范围设置LabVIEW类只包含私有成员数据,但可以为类的成员VI指定访问范围。成员VI的访问范围选项包含如下设置:公共(Public),任何VI都可以调用该成员VI;保护(Protected),仅该成员VI所在类及其子类中的VI可以调用该成员VI,在项目浏览器窗口中受保护的成员VI图标中有一个暗黄色的钥匙符号;私有(Private),仅该成员VI所在类中的VI可以调用该成员VI,在项目浏览器窗口中私有型的成员VI图标中有一个红色的钥匙符号。,23,6.3LabVIEW对象基本实现,在类上右击,选择属性后可以设置一个VI的访问范围,24,6.3LabVIEW对象基本实现,使用类在创建LabVIEW类的实例时,用户可直接将这个类的类库文件(.lvclass)作为控件或常量放置在相应程序的前面板或程序框图中;在LabVIEW类中,所有的私有数据被定义为一个簇,通过在成员VI的程序框图中调用函数来访问和操作这些数据;对LabVIEW类进行捆绑或解除捆绑时,节点上仅显示当前类私有数据的接线端,而不显示从父类继承的数据的接线端。,25,使用类获取大一成绩程序框图,6.4LabVIEW对象高级技巧,构造函数与析构函数在一般的面向对象程序设计语言中,对象在创建和销毁时会自动调用两个函数:构造函数和析构函数;构造函数的作用是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态,使对象具有自己的特征;析构函数则用来完成对象被删除前的一些清理工作,析构函数调用完成之后,对象将被销毁,相应的内存空间也被释放;在LabVIEW的面向对象编程中,构造和析构是隐含的,不需要用户编写或调用。,26,6.4LabVIEW对象高级技巧,内存分布在LabVIEW中,类的高效存储是一个挑战性的问题。一个类的数据包括从父类继承来的数据簇和自身的私有数据簇。,27,6.4LabVIEW对象高级技巧,在类实现时,LabVIEW需要为一个类分配数据空间,28,6.4LabVIEW对象高级技巧,动态分配动态分配是LabVIEW的一个特色,一个看似单个VI调用的节点在运行时实际上调用的是一组VI中的某个,这取决于运行时动态分配输入端连线上的值;每一个在连线上传递的对象都含有指向其类信息的指针,这个类信息包含了一个“动态分配表”,它是一个VI引用表;每个类首先复制了其父类的动态分配表,同时它用自身重写的VI方法替换父类中对应的方法,然后将没有重写的父类动态分配VI添加到表中。,29,6.4LabVIEW对象高级技巧,动态分配的示例,30,6.4LabVIEW对象高级技巧,XcontrolXControl可用于在LabVIEW中设计和创建复杂的控件,并且它的运行方式由后台运行的VI决定;XControl包括控件的动作;在VI中使用XControl可简化该VI的程序框图。,31,6.4LabVIEW对象高级技巧,XControl的创建和应用创建XControl:两种方法一是选择菜单项“FileNewOther FilesXControl”;二是在项目浏览器的右击快捷菜单中选择“新建XControl”。,32,6.4LabVIEW对象高级技巧,新建Xcontrol,33,新建的Xcontrol界面,6.4LabVIEW对象高级技巧,Xcontrol示例:双重温度计,34,Simple Dual Mode Thermometer XControl.xctl,6.4LabVIEW对象高级技巧,每个XControl包含必须以下四个模块:数据(Data)这是一个自定义类型控件,定义了XControl的数据类型;状态(State)也称为显示状态,是一种自定义类型控件,定义了所有影响控件外观的信息(除XControl的数据外);外观(Facade)外观VI的编写在XControl的设计中最为重要,它的前面板决定了XControl的外观,它的程序框图描述了XControl的功能;初始化(Init)第一次将XControl放在前面板,或当包含XControl的VI被加载到内存时,LabVIEW将调用Init模块。,35,6.4LabVIEW对象高级技巧,除了4个必须模块以外,在XControl中还可以创建属性、方法、VI、文件夹等;右击XControl,在“新建”目录下单击“属性”项创建属性,首先需要将属性命名并选择该属性的读/写模式,然后再编写属性的VI;将XControl拖放到前面板时,它就已经开始工作了,打开XControl的外观VI,其为运行状态,不可编辑,只有当所有调用了该XControl的VI全部关闭之后,才可以编辑外观VI;调用XControl的属性和方法与一般控件类似。,36,6.4LabVIEW对象高级技巧,Simple Dual Mode Thermometer XControl的应用示例前面板,37,6.4LabVIEW对象高级技巧,程序框图,38,6.4LabVIEW对象高级技巧,多态技术:多态函数在LabVIEW中,多态函数是指能够自动适应不同类型输入数据的函数;多态函数广泛出现在各种不同数据类型的操作中,包括数值函数、布尔函数、数组函数、簇函数、字符串函数及比较函数等操作。,39,6.4LabVIEW对象高级技巧,多态的加法函数,40,6.4LabVIEW对象高级技巧,多态技术:多态VILabVIEW提供了一些具有多态性的系统子VI;多态VI可在一个输入或输出端接收不同的数据类型;多态VI是具有相同模式连线板的子VI的集合,该集合中的每个VI均为多态VI的一个程序实例。,41,6.4LabVIEW对象高级技巧,创建多态VI创建多态VI时需考虑以下几个方面:多态VI中所包含的所有VI必须具有相同的连线板模式;多态VI每个实例连线板上的输入/输出端口必须与多态VI连线板上的输入/输出端口相对应;用来创建多态VI的VI不必包含相同的子VI和函数,每个VI的前面板也不必包含相同的对象,但是每个前面板上控件的数目至少应与组成多态VI连线板中的控件数目一致;在创建多态VI时隐藏多态VI选择器,就可以由连接到多态VI输入端的数据类型来自动选择使用哪个实例。,42,6.4LabVIEW对象高级技巧,创建多态VI示例首先在LabVIEW的File菜单中选择“新建多态 VI”,43,多态VI的初始界面,6.4LabVIEW对象高级技巧,然后创建两个将变体形数据转化为String数组的VI。,44,将二维变体形数据转化为二维String数组,6.4LabVIEW对象高级技巧,45,将一维变体形数据转化为一维String数组,6.4LabVIEW对象高级技巧,最后在多态VI的初始界面中将这两个VI添加到“实例VI”(Instance VIs)中,编辑好图标,并保存为DB_VarToData.vi,该VI即为一个多态VI。,46,变体形数据转化为String数组的多态VI,6.4LabVIEW对象高级技巧,锁定在LabVIEW中,可以通过锁定LabVIEW类来保护类的私有数据信息;锁定类可阻止LabVIEW类用户访问应用程序内部的成员VI,从而预防将错误引入应用程序。,47,6.4LabVIEW对象高级技巧,锁定类的设置,48,在类属性对话框中锁定类,6.4LabVIEW对象高级技巧,类未锁定与锁定时即时帮助的区别如果一个LabVIEW类未被锁定,则当光标在类的连线上移动时,即时帮助窗口将显示该类的私有数据,以及该类所有未锁定的父类的私有数据;当光标在锁定的类的连线上移动时,即时帮助窗口中仅显示连线数据类型。,49,6.4LabVIEW对象高级技巧,50,类未锁定的即时帮助,类锁定的即时帮助,6.4LabVIEW对象高级技巧,添加对类的描述在类的属性框中单击选择“说明信息”(Documentation)选项,在“说明”(Description)中可以添加对类的描述。,51,6.4LabVIEW对象高级技巧,探针探针是LabVIEW程序调试的主要工具之一;在LabVIEW类连线上可以使用通用探针来调试数据,通用探针显示了运行时该类的类名、类私有数据和该类父类的私有数据;用户可以根据需要为LabVIEW类创建自定义默认探针来实现更有效的数据调试。,52,6.4LabVIEW对象高级技巧,未锁定与锁定的探针的区别,53,未锁定的探针,锁定的探针,6.4LabVIEW对象高级技巧,创建自定义探针在希望使用自定义探针的连线上右击,选择“自定义探针”(Custom Probe)项,下拉列表中可以选择已有的自定义探针,或通用探针(Generic Probe),或控件,或者新建一个自定义探针。,54,6.4LabVIEW对象高级技巧,Truck Custom Probe.vi的程序框图,55,6.4LabVIEW对象高级技巧,自定义探针的使用,56,6.5实例介绍,通过LabVIEW Example的一个电路板检测(Board Testing.lvproj)的实例来进一步说明面向对象编程的设计思路,以及其相比于传统面向任务编程的优势。,57,6.5实例介绍,测试要求某公司生产了三种计算机板卡,分别为低端数据采集卡(Basic DAQ Board)、高端数据采集卡(Elite DAQ Board)和GPIB板卡(GPIB Board);该公司为了检测三条流水线上每一块板卡的元件是否摆放正确,在每一条流水线上都放置了一个摄像头,将板卡的图片发送到同一台计算机上,计算机通过检测程序来判断板卡的各个元件是否摆放正确。,58,6.5实例介绍,三种板卡的元件摆放方式,59,低端数据采集卡,高端数据采集卡,GPIB板卡,6.5实例介绍,解决方案针对上述测试要求,可以采用面向任务和面向对象两种解决方案。,60,6.5实例介绍,面向任务的解决方案(Test Boards_TASK.vi),61,模拟产生来自摄像头的板卡图像,获取板卡类型及板卡图像,对每种板卡用单独的VI进行测试,获取测试板卡的ID号,获取测试板卡的类型,输出测试结果,6.5实例介绍,面向任务的解决方案(Test A.vi),62,6.5实例介绍,面向对象的解决方案(Test Boards_OBJECT.vi)程序使用三个子VI替代了面向任务的解决方案中相对复杂的Case结构。,63,根据输入的板卡类型产生相应的对象,检测输入的对象,获取测试板卡的ID号及类型,6.5实例介绍,面向对象的解决方案(Check Image Matches Design.vi),64,6.5实例介绍,面向对象的优势面向对象的方法是将系统分解为更加相对独立的模块,从而增强了系统的可扩展性和代码可重用性;面向对象方法使用了更多的子VI,其中每一个子VI都对应一个非常具体的任务,这种方法使代码的可读性得到了很大的提高;当应用程序需要进行改动时,面向对象会显示出更大的优势来。,65,6.6提示与建议,提示与建议LabVIEW提供面向对象的支持不是对原有LabVIEW程序开发方法的彻底革命,面向对象并不适合所有的实际应用,它仅仅是一个工具;如果需要建立某个用于长期维护或升级的应用程序,则面向对象是一个明智的选择;面向对象编程可以帮助程序员更好地组织代码、维护代码,使LabVIEW项目更具有可管理性。,66,6.6习题,使用面向对象的方法,编写在二维平面对AB两点连线的程序,其中A点坐标为(X1,Y1),B点坐标为(X2,Y2),考虑使用3种类:点类、线类和连接类。界面如图所示。在习题1的基础上,考虑如何实现三点两两连线,其中A点坐标为(X1,Y1),B点坐标为(X2,Y2),C点坐标为(X3,Y3)。,67,6.6习题,使用多态的方法,编写程序实现以下功能:(1)如输入为字符串,则将字符串中的所有空格去掉;(2)如输入为字符串的一维数组,则将该数组中所有字符串的空格去掉。,68,6.6习题,编程实现以下功能:(1)设计名为“Generator”的XControl。其中signal type包含Sine Wave,Triangle Wave,Square Wave和Sawtooth Wave 4种类型,如果选择Square Wave类型,那么需要显示“duty cycle(%)”控件,如图 (a)所示;否则就隐藏该控件,如图(b)所示。(2)尝试为设计的XControl创建属性和方法。(3)使用设计的XControl,编写产生相应波形的程序。 (a) (b),69,