陈南南
(厦门大学嘉庚学院, 福建 厦门 363105)
在面向过程的结构化编程中,数据传递通常以函数间的参数传递方式实现。但在面向对象的事件驱动机制的编程模式中,由于类的存在,使得数据更多地是在对象间进行传递。特别是在多窗体程序中,窗体间的数据传递更加频繁。因此,如何规范安全地实现不同对象间的数据传递成为关键。
在面向对象编程中,本类中的函数参数传递方法与面向过程的编程方法类似,本文就不进行阐述了。为了更直观地了解数据在不同对象间的传递,下文以一个基于C#的多窗体小程序为例,分析程序中出现的
几种数据传递方法。如图1所示,Form1中,点击字号按钮后,显示Form2窗体,由该窗体中的滑动条控制Form1中标签控件中的文本字号,滑动条当前value值为标签控件中当前字号大小值。这个小实例虽然简单,但其中包含了几种典型的数据传递方式,这几种方式可以分成两个阶段:主窗体向从窗体传递、从窗体向主窗体传递。
图1 实例截图
Form1与Form2分属不同的类,在不同的类对象间进行参数传递,主要有以下几种方式。
在类定义过程中定义一个静态变量,在不同类对象中应用时可以直接用类名引用该变量,这种方式实现简单,但不符合面向对象的封装思想,而且不同的类对象只能共用该变量,无“个性”。在本例中不适用。
本例中,Form2显示时需要接收主窗体传递过来的主窗体对象参数以及标签当前字号值。在Form2中设置一个public的有参数构造函数。
在Form1中点击字号按钮创建Form2对象时,在按钮单击事件处理函数中通过构造函数传递参数,Form2 f2=new Form2(this,(int)label1.Font.Size)。
使用构造函数传递参数实现简单,适合与传递对象建立时所需的初始值。但这种方式只能是一次性传递,下次再用构造函数传递参数时,传递的目标是一个新的对象,而不是原来的从窗体了。
当需要多次从主窗体中接收数据时,可以在从窗体中定义一个public变量,在主窗体中用对象名.变量名的格式进行赋值传递,但这种方式不符合面向对象编程思想中封装性原则,且不安全。所以可以在从窗体中定义一个public类型的可读写属性,在主窗体中用对象名.属性名的格式进行读写设置,具体实现方法在本例中不做详细实现。
在从窗体创建并显示后,根据滑动条的左右滑动,修改主窗体中标签文本字号,这就需要从窗体向主窗体传递滑动条的Value属性值。有两种实现方法:
将主窗体Form1中的标签Label1控件的modifiers属性由Private改为Public,这样就可以在从窗体的相应事件处理函数中对标签控件的Font属性进行直接赋值修改。
但从面向对象程序的封装性及安全性考虑,随意修改类成员的访问权限是不可靠的。所以最佳办法应该利用委托与事件的消息订阅机制来传递数据。
委托与事件是面向对象编程思想中的重要概念之一,也是最不易理解的概念之一。委托在功能上它类似C语言的函数指针,目的是通过创建委托类型对象去调用函数。而事件则是一种特殊的委托,事件能完成的委托也能够完成,但事件的封装性及安全性要求更高,是一种特制的更为专业化的委托。二者的主要区别在于:第一,事件只能在本类以外用“+=”和“-=”去订阅/取消订阅代理,委托不管在本类外部还是内部都可以用“+=”、“-=”和“=”订阅 /取消订阅代理;第二,事件只能在本类内部“触发”,委托不管在本类内部还是外部都可以“调用”。即:事件,只有本类才能激发这个事件。
C#是面向对象的事件驱动的编程工具,.net Framework的事件机制使得编程更加快捷简便。大部分初学者在使用系统控件的各种事件时都熟悉得很快,但在对自定义事件的具体定义、订阅以及触发过程却往往一知半解。下面我们就利用数据传递过程简单介绍事件的处理步骤。
在本例中当从窗体Form2中的滑动条发生滑动后,立即向主窗体发生当前value属性值作为标签字号,因此需要首先定义一个委托类型,然后在Form2中定义一个关于该委托类型的事件,并在滑动条的滑动事件处理过程中触发该事件。
public delegate void sendfontsize(int fs);//声明委托,代表无返回值,参数为整型的函数
public partial class Form2:Form
{public event sendfontsize send;//定义事件,为上述委托类型
由于C#的开发工具Visual Studio功能过于强大,在方便我们编程工作的同时,也隐藏了许多相对基础的底层概念及操作,使得许多初学者对面向对象的许多概念更难以理解其中的具体定义及使用过程,希望本文能对读者有所帮助,加深对相关概念的理解。
[1](美)Stephen C.Perry著.C#和.NET核心技术[M].肖斌,王小振等译.北京:机械工业出版社,2007.
[2]明日科技编著.Visual C#开发技术大全[M].北京:人民邮电出版社,2007.
[3]苏杭丽.C#中数据传递方式的教学模型设计[J].计算机时代,2011,(03).