2011年9月8日,第一稿
8.5 LabVIEW图形化语言编程范式之三——面向对象编程
本章前面的内容中,我们已经介绍了LabVIEW图形化语言的两种编程范式——过程化编程和事件驱动编程。我相信对于绝大多数LabVIEW的使用者而言,他们通常采用这两种编程范式在进行图形化程序设计,一直以来我也亦如此。
LabVIEW自从诞生以来,一直延续的基本编程范式是过程化编程范式(数据流运行机制所决定的)。自LabVIEW6.1发布以后,引入了事件驱动的编程机制。在LabVIEW8.20发布时正式引入了面向对象的编程范式。从此LabVIEW成为一种多范式的图形化编程语言。
数十年来,尽管面向对象的编程方法一直是软件开发的标准方法,但我相信对于大多数LabVIEW开发者而言这仍将是一个全新的概念。现在我期待与大家一起学习、了解面向对象编程的基本概念,以及如何在LabVIEW中使用这种面向对象的编程方法。
但是,我要非常遗憾的告知大家两件事情:
第一,本书的章节排列出现问题
面向对象编程的基本操作都是在项目中实现、完成的,遗憾的是到目前为止本书还没有介绍到这方面的基本内容(项目管理预计在第10章给出)。当然,这只是逻辑问题(以后有机会整理改正之),如果你已经掌握的这方面内容,估计这个问题对你的影响不大。
第二,笔者的能力先天不足
坦白的与大家说:到目前为止我没有任何面向对象编程的理论基础知识和实践经验,我是在尽自己最大的努力来与大家一同学习这方面的知识。所以,如果内容中出现这样或那样的错误时,请大家一定给予谅解。来自任何方面、任何善意的批评和指正我都欢迎!
基于这样两个原因,本小节的内容会断续编写(因为我也在学习中...)。
LabVIEW自从诞生以来,一直延续的基本编程范式是过程化编程范式(数据流运行机制所决定的)。自LabVIEW6.1发布以后,引入了事件驱动的编程机制。在LabVIEW8.20发布时正式引入了面向对象的编程范式。从此LabVIEW成为一种多范式的图形化编程语言。
数十年来,尽管面向对象的编程方法一直是软件开发的标准方法,但我相信对于大多数LabVIEW开发者而言这仍将是一个全新的概念。现在我期待与大家一起学习、了解面向对象编程的基本概念,以及如何在LabVIEW中使用这种面向对象的编程方法。
但是,我要非常遗憾的告知大家两件事情:
第一,本书的章节排列出现问题
面向对象编程的基本操作都是在项目中实现、完成的,遗憾的是到目前为止本书还没有介绍到这方面的基本内容(项目管理预计在第10章给出)。当然,这只是逻辑问题(以后有机会整理改正之),如果你已经掌握的这方面内容,估计这个问题对你的影响不大。
第二,笔者的能力先天不足
坦白的与大家说:到目前为止我没有任何面向对象编程的理论基础知识和实践经验,我是在尽自己最大的努力来与大家一同学习这方面的知识。所以,如果内容中出现这样或那样的错误时,请大家一定给予谅解。来自任何方面、任何善意的批评和指正我都欢迎!
基于这样两个原因,本小节的内容会断续编写(因为我也在学习中...)。
8.5.1 LabVIEW为什么要引入面向对象的编程范式
估计大多数人可能都想知道我们为什么要学习这种面向对象的编程方法。的确,我们应该给出一个比较充分的理由。
应该讲,最充分的理由就是:面向对象的编程方法已经在软件开发产业获得巨大的成功这样一个现实,要知道在软件设计中对于复杂事物的处理原本并不是人们所擅长的。面向对象的编程方法可以将复杂的问题分解为许多更容易处理的小问题。这个优点在大型项目开发时将会显现的更加清晰。因为项目中的每个成员只需专注于复杂软件体系中与自己相关的那部分内容。
过程化编程要求程序员用按部就班的算法看待每个问题。很显然,并不是我们所遇到的问题都适合用过程化的思路来解决。这就导致其它编程范式或语言就不断涌现出来,面向对象编程编程范式就是其中的一个。
在面向对象的编程范式没有出现之前,没有一种编程范式可以达到过程化编程范式的普及程度。面向对象编程范式的出现打破了这样的格局,其普及程度已经接近或超过过程化编程范式。
面向对象编程具有很多特点,比如分析问题和看问题的角度不同,它将世间万物都看成对象来处理,同时对象被归结为不同的类,并用类来表示通用特性。通过继承可以实现类与类之间特定的特性相互传递。利用封装可以使得对象更容易进行修改和调整,并复用到其它应用程序中。
面向对象编程的方法从对事物的认识上很类似人类感知现实世界的方式。面向对象的编程方式使程序员更容易设想问题的解决方案。适合大型应用项目中的团队设计,增加程序的弹性和可维护性,并可大大提高编程效率。
LabVIEW作为一种图形化编程语言,它设计的初衷就是降低工程师和科学家在程序设计方面的复杂程度。所以,它并不希望LabVIEW被局限在某种编程范式中。引入面向对象编程范式是想通过图形化的方式进一步降低面向对象编程范式的复杂度。使工程师和科学家也可以使用这种面向对象的编程范式。
对于LabVIEW开发者而言,与我们所习惯的数据流编程相比,面向对象的编程方法允许模块化的软件设计。由于采用模块化的面向对象的编程方法,大大简化了软件体系结构建模过程。 模块化也使得软件的维护和管理成为更加容易和更加简单的工作。并在软件的整个生命周期中都可以实现对软件的有效管理。
面向对象编程通常使用大写字母:OOP(Object-Oriented Programming)来表示。所以LabVIEW面向对象编程通常使用大写字母:LVOOP(LabVIEW Object-Oriented Programming)来表示。
LVOOP的适应领域:
当然,习惯了数据流编程的用户对面向对象的编程范式还是比较陌生,甚至是觉得有些概念是难以理解的。我们希望通过本节的介绍大家会在这方面有一定程度上的提高。
应该讲,最充分的理由就是:面向对象的编程方法已经在软件开发产业获得巨大的成功这样一个现实,要知道在软件设计中对于复杂事物的处理原本并不是人们所擅长的。面向对象的编程方法可以将复杂的问题分解为许多更容易处理的小问题。这个优点在大型项目开发时将会显现的更加清晰。因为项目中的每个成员只需专注于复杂软件体系中与自己相关的那部分内容。
过程化编程要求程序员用按部就班的算法看待每个问题。很显然,并不是我们所遇到的问题都适合用过程化的思路来解决。这就导致其它编程范式或语言就不断涌现出来,面向对象编程编程范式就是其中的一个。
在面向对象的编程范式没有出现之前,没有一种编程范式可以达到过程化编程范式的普及程度。面向对象编程范式的出现打破了这样的格局,其普及程度已经接近或超过过程化编程范式。
面向对象编程具有很多特点,比如分析问题和看问题的角度不同,它将世间万物都看成对象来处理,同时对象被归结为不同的类,并用类来表示通用特性。通过继承可以实现类与类之间特定的特性相互传递。利用封装可以使得对象更容易进行修改和调整,并复用到其它应用程序中。
面向对象编程的方法从对事物的认识上很类似人类感知现实世界的方式。面向对象的编程方式使程序员更容易设想问题的解决方案。适合大型应用项目中的团队设计,增加程序的弹性和可维护性,并可大大提高编程效率。
LabVIEW作为一种图形化编程语言,它设计的初衷就是降低工程师和科学家在程序设计方面的复杂程度。所以,它并不希望LabVIEW被局限在某种编程范式中。引入面向对象编程范式是想通过图形化的方式进一步降低面向对象编程范式的复杂度。使工程师和科学家也可以使用这种面向对象的编程范式。
对于LabVIEW开发者而言,与我们所习惯的数据流编程相比,面向对象的编程方法允许模块化的软件设计。由于采用模块化的面向对象的编程方法,大大简化了软件体系结构建模过程。 模块化也使得软件的维护和管理成为更加容易和更加简单的工作。并在软件的整个生命周期中都可以实现对软件的有效管理。
面向对象编程通常使用大写字母:OOP(Object-Oriented Programming)来表示。所以LabVIEW面向对象编程通常使用大写字母:LVOOP(LabVIEW Object-Oriented Programming)来表示。
LVOOP的适应领域:
- 某些需要长期维护的VI
- 大型应用程序开发
- 同一项目中的多个开发者
当然,习惯了数据流编程的用户对面向对象的编程范式还是比较陌生,甚至是觉得有些概念是难以理解的。我们希望通过本节的介绍大家会在这方面有一定程度上的提高。
8.5.2 LabVIEW中的类和对象
在前面(第6章)我们介绍过的应用程序控制以及控件或VI的属性和方法时曾涉及到类和对象的一些简单概念。
LabVIEW并不是纯粹地面向对象的编程语言。但是它有些概念的用语与面向对象的用语相类似,比如类和对象的用语。
在LabVIEW中,对象的概念是很广泛的。这一点在LabVIEW的“类浏览器”中的对象库中可以看得更清楚。
具体操作是:在开发环境下选择:
》查看
》类浏览器
系统会弹出一个类浏览器对话框,参见下图。
LabVIEW并不是纯粹地面向对象的编程语言。但是它有些概念的用语与面向对象的用语相类似,比如类和对象的用语。
在LabVIEW中,对象的概念是很广泛的。这一点在LabVIEW的“类浏览器”中的对象库中可以看得更清楚。
具体操作是:在开发环境下选择:
》查看
》类浏览器
系统会弹出一个类浏览器对话框,参见下图。
从上图可以看出,通过对象库的下拉菜单可以选择不同的对象集合(库中也包含了LabVIEW类)。不同的对象库则包含不同的类,不同的类中包含不同的属性和方法。
实际上,我们前面第6章所涉及到的应用程序控制以及控件或VI的属性和方法都隶属于VI服务器类。
我们应该注意到这样一个事实:上述的类和对象都是已经确定性的,也可以说是都是已经存在的。在这里我们不能够创建新的类和对象,我们只能使用这些类和对象。
实际上,我们前面第6章所涉及到的应用程序控制以及控件或VI的属性和方法都隶属于VI服务器类。
我们应该注意到这样一个事实:上述的类和对象都是已经确定性的,也可以说是都是已经存在的。在这里我们不能够创建新的类和对象,我们只能使用这些类和对象。
8.5.3 LVOOP中的类和对象
LabVIEW中引入了面向对象编程的范式后,必须规范一些涉及到面向对象编程的一些基本概念,使得这些概念即不会与图形化语言原有的概念发生冲突,又不能偏离面向对象编程中的原有的概念[20]。比如在LabVIEW中原来已经有了类(VI服务器类等)和类型(自定义类型)的概念。
因此,在LabVIEW面向对象编程(LVOOP)中,特别将LVOOP中的类定义为:LabVIEW类。
LabVIEW类
源于数据流编程的需要,我们可以在程序设计中通过对具体任务的抽象处理,创建自己的LabVIEW类作为特定的数据类型。并依此设计出LabVIEW类的实例对象。
LabVIEW类的特点:
与前面所介绍的VI服务器类不同,现在我们可以创建自己的LabVIEW类,并可以根据实际应用抽象出特定类中的对象。
通常对象也被称为类的实例,或者说类是对象的集合。
因此,在LabVIEW面向对象编程(LVOOP)中,特别将LVOOP中的类定义为:LabVIEW类。
LabVIEW类
源于数据流编程的需要,我们可以在程序设计中通过对具体任务的抽象处理,创建自己的LabVIEW类作为特定的数据类型。并依此设计出LabVIEW类的实例对象。
LabVIEW类的特点:
- LabVIEW类在形式上类似一个簇控件。簇中所包含的元素就是这个类将涉及到的数据类型(控件或常数),但是在数据操作上会有某些特殊的要求。
- LabVIEW类用于创建用户自定义的数据类型和包括对数据执行的操作(方法)。
- LabVIEW类通过封装可以使程序更易修改,且不影响应用程序中的其他代码。
- LabVIEW类可以通过继承来建立类之间的层次关系,有利于代码复用和组织。
与前面所介绍的VI服务器类不同,现在我们可以创建自己的LabVIEW类,并可以根据实际应用抽象出特定类中的对象。
通常对象也被称为类的实例,或者说类是对象的集合。
8.5.4 创建LabVIEW类
实现LVOOP最关键的步骤是创建LabVIEW类,而创建LabVIEW类的关键是如何抽象处理我们所面临的任务。如果不能够正确抽象出你所期待的LabVIEW类,程序设计是根本无法进行下去。
LVOOP只是一种编程工具或编程方法,它的核心编程思想是将世间万物都视为对象,对象中包括了数据类型,通过对象的属性和方法来操控执行对象的行为。相似的对象被归结为一类,通过类的继承来扩展更多的对象。所以准确的抽象出特定的类才能够灵活有效的使用这种工具,并很快达到工程上的实用化的目的。
遗憾的是,许多讲述LVOOP的书籍很少给出工程意义上的抽象处理实例。大多数LVOOP的例子都是选择动物类、人员管理类等进行表述。对于我们这些初级学者而言,从基本概念上很容易理解,但是在工程上如何实用化往往很茫然,真的不知如何处理为好。
实际上,这还是在抽象处理方面遇到的真正困难。
笔者也期待能够采用更贴近工程上的应用来表述这部分内容。但是,千万不要忘记我们是在共同学习。显然,对于这部分内容,我们更期待这方面的意见或建议的反馈。
实际上,到现在我才知道,创建LabVIEW类并不一定要在项目中进行(前面我确是这样谈的)。
创建一个LabVIEW类可以在LabVIEW的启动界面选择:
》文件
》新建
》其它文件、类
来创建一个LabVIEW类,参见下图。
LVOOP只是一种编程工具或编程方法,它的核心编程思想是将世间万物都视为对象,对象中包括了数据类型,通过对象的属性和方法来操控执行对象的行为。相似的对象被归结为一类,通过类的继承来扩展更多的对象。所以准确的抽象出特定的类才能够灵活有效的使用这种工具,并很快达到工程上的实用化的目的。
遗憾的是,许多讲述LVOOP的书籍很少给出工程意义上的抽象处理实例。大多数LVOOP的例子都是选择动物类、人员管理类等进行表述。对于我们这些初级学者而言,从基本概念上很容易理解,但是在工程上如何实用化往往很茫然,真的不知如何处理为好。
实际上,这还是在抽象处理方面遇到的真正困难。
笔者也期待能够采用更贴近工程上的应用来表述这部分内容。但是,千万不要忘记我们是在共同学习。显然,对于这部分内容,我们更期待这方面的意见或建议的反馈。
实际上,到现在我才知道,创建LabVIEW类并不一定要在项目中进行(前面我确是这样谈的)。
创建一个LabVIEW类可以在LabVIEW的启动界面选择:
》文件
》新建
》其它文件、类
来创建一个LabVIEW类,参见下图。
鼠标点击上图中的确定,系统会弹出一个对话框要求你输入新类的名称,比如我们选择默认的类名,点击确定就会看到下图所示的类1。
上图中我们看到类1的图标为一个蓝色的正方体,而类1中仅包含了一个类1的控件,它的图标中的圆柱体表示它所包含类的数据,它的图标中的小钥匙表示属于私有数据类型。点击它可以打开它的前面板,参见下图。
在这里我们可以在类私有数据的簇中添加我们所期待的多种数据类型(控件),现在这里是空的。
事实上,现在我们已经创建了一个LabVIEW类(类1)。但是我们并没有赋予它真正上的意义,表括类名和数据类型,只是通过它来见识一下LabVIEW类的基本结构和形式。这里并没有融合任何工程上的意义。
下面我们会试着创建一个工程上具有实际意义的LabVIEW类。
事实上,现在我们已经创建了一个LabVIEW类(类1)。但是我们并没有赋予它真正上的意义,表括类名和数据类型,只是通过它来见识一下LabVIEW类的基本结构和形式。这里并没有融合任何工程上的意义。
下面我们会试着创建一个工程上具有实际意义的LabVIEW类。
8.5.5 LabVIEW 面向对象编程实例演示

当我们面对这样的情况:比如需要写一个LabVIEW与硬件进行GPIB通信的程序,可是我们手头上并没有硬件在手。或者,在进行产品展示时,我们需要一个没有硬件参与的演示程序。我们应该有办法来解决类似这样的问题。
现在借助于LVOOP来进行程序设计,很容易地从一开始就包括硬件仿真功能。在这个视频中演示了如何使用LabVIEW类方法实现了GPIB通讯的硬件仿真设计。你可以在上面的链接中下载程序代码。
实际上,并非一定必须使用LVOOP才能完成软件仿真的功能,采用其它设计方法一样可以实现仿真的功能。但是,LVOOP的设计方法更容易实现模块化设计,并更方便添加和修改应用程序。
下面就来看看该演示程序的代码部分,参见下图。
下面就来看看该演示程序的代码部分,参见下图。
在上图所示的硬件仿真(Hardware Emulation)项目中,首先需要创建一个LabVIEW类(父类),本实例的硬件对象针对的是DMM,所以必须创建一个DMM类(父类),包括该类的数据和方法,参见下图。
创建DMM类之后,必须在指定该类的所包含的数据类型,以及该类可接受的操作方法。
其数据类型参见下图。
其数据类型参见下图。
类私有数据中的内容很简单,包括一个VISA资源名控件、一个字符串控件和一个数值控件。DMM类的方法其实就是一些VI,通过这些VI来控制执行对象的行为。
在图8-11中我们还可以看到两个DMM子类,分别是:Agilent34401.lvclass和DMM Emulator.lvclass。他们与DMM类之间的关系是继承关系。参见下图。
在图8-11中我们还可以看到两个DMM子类,分别是:Agilent34401.lvclass和DMM Emulator.lvclass。他们与DMM类之间的关系是继承关系。参见下图。
有了这种继承关系,如果应用程序设计中需要,我们就可以扩展更多的子类。比如我们还可以创建DMM Fluke8840.lvclass(Fluke公司的一种DMM,类似于安捷仑的DMM34401)等。同时并不需要对其它子类的程序进行任何改动。
这里的子类可以看成就是我们所提到的对象,比如EMUL对象、A34401对象等等。
显然这是一种模块化的设计方法。这就是LVOOP的优势所在。
这里的子类可以看成就是我们所提到的对象,比如EMUL对象、A34401对象等等。
显然这是一种模块化的设计方法。这就是LVOOP的优势所在。
继承
首先我们先看看该项目的类层次结构,参见下图。
子类都继承了父类的那些东西?
数据
子类继承了父类的数据类型。假如我们打开子类的.ctl控件可以看到其簇是空的,它是继承了父类的数据类型。
方法
子类具有原来父类所公开的属性和方法。同时又创建了属于各自子类特有的属性和方法。
关于LVOOP只能介绍到这个层度(受我个人能力所限),感兴趣的读者可以通过视频和参照本实例代码分析使用。
例子代码中分为两种,一种是非面向对象编程范式,另一种是面向对象的编程范式,参见下图。
数据
子类继承了父类的数据类型。假如我们打开子类的.ctl控件可以看到其簇是空的,它是继承了父类的数据类型。
方法
子类具有原来父类所公开的属性和方法。同时又创建了属于各自子类特有的属性和方法。
关于LVOOP只能介绍到这个层度(受我个人能力所限),感兴趣的读者可以通过视频和参照本实例代码分析使用。
例子代码中分为两种,一种是非面向对象编程范式,另一种是面向对象的编程范式,参见下图。

source2009.rar | |
File Size: | 240 kb |
File Type: | rar |