资源描述
易飞扬面向对象编程易飞扬面向对象编程1分类2启动3公开4私有4静态4非静6对象7成员8初始9清理10属性10事件11创建13销毁13重载13封装15继承15多态16接口17总结19由于“易语言.飞扬”还未完全成型,在此过程中如果有所改动,教材也会相应的改动,但是对于面向对象的编程来说,基本上是不会变的,因此本书作者才有信心将面向对象的编程方法写出来。之所以本书的名称中有“编程思想”一样,我们不是为了编程而去编程,那种整天加班,一天到晚累得半死的生活并不是我们这些程序员理想中的生活,对于工作与生活的态度,也影响到我们编程中去,如何仿照自然的方法去编程,去生活同样具有重要的意义。那么什么是“对象”呢?这个问题一直困扰着很多编程的入门者,有说对象就是组件,有说对象就是类的实体化,虽然我不反对用这些术语,但我反对让初学者搞不明白,实际上,“对象”就是你的一个好朋友,这个好朋友的功能强大,能够帮助你完成你所设计的事情,那么,下面我们就介绍一直在你身边的这个好朋友吧。分类物以类聚,人以群分,朋友也是这样,如果你交个好朋友,那么就会受益无穷,如果你交了个损友,那么后果不难想象,所谓近墨者黑,近朱者赤,君子之交淡如水,也就是说交一些具有平常心的朋友,不会让你去冒险,不会让你心烦意乱。好了,想法是好的,那么就会去找,如果真的找到了,那么就恭喜你,如果找不到,也不必伤心。那么我们理想中的好朋友就是对象,而真实的好朋友就是对象的实体,我们把他们分为一类人“好朋友”,还有就是“普通朋友”、“同事”、“老师”、“陌生人”等。通过以上,可以了解到面向对象编程中“类”与“对象”的关系。“类”相当于“好朋友”、“普通朋友”、“同事”、“老师”、“陌生人”等这些思想的划分,而具体的某个人就是类的“实际对象”。理想中的好朋友具有相关的特性,比如有身高,年纪,性格等信息,也可以在人生的道路上帮助你成长。在面向对象中,把“相关特性”称为“数据成员”,虽然听起来很奇怪,但大家只要了解到,与老易语言中的属性是差不多的。在面向对象中,把“功能”称为“方法”,虽然听起来很奇怪,但大家只要了解到,与老易语言中的方法命令是差不多的。下面就来看第一个易飞扬类的代码吧。上述代码中,控制台就是一个对象,也是你的好朋友,他具有“输出行”这样的方法命令,后面所接就是他的参数:“输出的文本”。而“输出的文本”是在上一行中进行了定义的,是一个文本变量,并且内容是“易语言,你好!”,这样一想,这个具体的好朋友还没有分类呢,于是将这个好朋友分为“启动类”,这个行为作为“启动类”的一个“启动”方法去执行。启动上面已经说过了,在上述这段代码中,有一个类“启动类”,这是我们对好朋友的划分,在该类中有一个方法“启动”方法,这是好朋友能做的事情。花括号里面的代码就是事情的具体步骤。好了,上述代码是可以执行的,大家还记得如何运行吗?不会的请看本书第一章节中的内容。在易飞扬中,程序的运行要依赖一个很重要的类它的类名为“启动类”。在“启动类”的下面有一个必有的方法“启动”方法,用法如其名,该方法是易飞扬程序的入口,也就是说,易飞扬的程序要从这个方法下面的代码进行运行。大家可以把这个“启动”方法看成是老易语言中的“_启动子程序”子程序。这样大家就可以很容易的看懂上面的代码了。注意了,“启动类”必须是“公开”的;而“启动”方法必须是“公开”且“静态”属性。大家先不要管什么是“公开”、“静态”,只要记下来就好了,继续看下面的文字吧。在“启动”方法中的代码,相信大家也能理解到了,是用控制台输出一行文字,文字的内容是“易语言,你好!”。不管如何,大家跟我学编程,我是不会亏待大家的,给大家一个小诗来说明我的归纳结果,大家有空就将这个口诀背下来哦,当出现对好朋友不理解时,只要背一下这个小诗,就基本上能解决问题了。口诀一:面向对象靠分类;声明类有属性表。公开大家都能用;私有隐藏保安全。内部静态调静态;外部类名加成员。非静创建类对象;对象名加类成员。面向对象靠分类;(面向对象中由类组成基本单位,一个类中有多个方法)声明类法有属性。(类有类的属性表,方法有方法的属性表)内部静态调静态;(在内部(类中)静态成员只能被静态成员所调用;)外部类名加成员。(而在外部(类外),只能通过“类名.”加成员名的方法进行调用。)非静创建类对象;(“非静态”成员的使用方法是:用类生成的“对象名”“.”类成员)对象名加类成员。(同上)公开大家都能用;(具有公开属性的类或方法,在其他的类或方法中可以直接调用,“公开”就是可被调用,其方法的引用就是类名+方法名即可。)私有隐藏保安全。(私有属性只是为了安全考虑,不向其他程序员公开,因此使用时只能在类的内部使用)难免本文还是要先来说明一下这些类或类成员名称前面的这些名词是做什么用的。公开面向对象靠分类;声明类有属性表。公开大家都能用;私有隐藏保安全。私有了解“公开”与“私有”哈哈,现在的人都是说自己有人权保护的,因为每个人都有自己的隐私,你的好朋友也不例外,当你的好朋友出现在你面前时,他公开了他的形象和语言,以及行为,但他回家后,是自己会吃饭、睡觉等,这些是不会公开给你看的哦。这样的好处是,你的好朋友不会随时公开他的行为,他就具有自主性,自动性,对他也是个保持哦。在面象对象中也是这样,当公开时,其他人都是可视的可调用的,但也设置一个“私有”属性,对这个类进行保护,保护的重要意义在于,这些都是内部的工作,自动完成的,不需要其他人为的干涉,否则就是干涉内政,或干涉别人的隐私罗。无论类、还是类中方法与属性,都可以设定它对外部是否可见,这个“可见”便是在被外部应用时是否可被调用。“公开”就是可被调用,而“私有”则不能。私有是面向对象中的一个重要工具,用于保护一些不想被外部调用的功能实现,保证安全性。静态内部静态调静态;外部类名加成员。非静创建类对象;对象名加类成员。了解“静态”与“非静态”你的好朋友可有不同的类型哦,有的是好静,喜欢听你的诉说,有的好动,自己就滔滔不绝,让人发笑,一般人都是喜欢安静,静胜燥,柔胜钢,阴盛阳衰,我也说多了,哈哈。方法具有“静态”属性,如果没有这个属性就说明是“非静态”的方法。“静态”从字面上是很难理解的,在我看来,只是给方法加上了一些限制而已。在内部(类中)静态成员只能被静态成员所调用;而在外部(类外),只能通过“类名.”加成员名的方法进行调用。在外部调用静态方法时,也可以把它看作老易语言中的“子程序”,这样大家可能会更好的理解它。好,给大家一个例程,以说明静态的调用方法是与老易语言中的一样的。下面是一个“好朋友”的类,其中明两个方法命令:“说话”和“行走”,代码如下:调用程序代码如下:运行结果如下图所示:可以看到以上的静态方法的调用,都与原老易语言的“子程序”或组件的调用方法是差不多的。当然了,当一个方法公开时,在其他类中是可以调用的,如果一个方法是私有的,那么在其他类中就不可调用。如将上述“说话”或“行走”改为私有属性,那么在“启动”方法中就不能调用了。非静“非静态”成员的使用方法的关键在于先用“对象”创建后再使用创建的对象调用。将上述的做一个反例来用,例如:将上述代码中的“说话”和“行走”方法命令中的静态属性去掉,就不能通过编译,代码如下:如果我们改为以下的调用方式,就又可以进行正常的编译运行了:上述代码中,用好朋友这个类,生成了一个新的对象“张三”,由于张三已成为好朋友的一个具体的对象,因此使用此对象调用这个类中的方法命令“说话”和“行走”。而大家在实际编程中,可以将方法命令换成你想要操作的其他功能,如建立菜单,打开窗口,处理数据等,也就实现了你的面向对象的程序了。“非静态”成员的使用方法是:用类生成的“对象名”“.”类成员其中“类成员”可以是非静态的数据和非静态的方法命令。对象下面大家可能会产生个疑问,一是在类的内部调用非静态方法命令时,是否也需要先声明一个对象呢?解决疑问的方法是自己动手,写几个不同的例子,用易飞扬编译后来验证一下。下面进行例子的比较。先来研究一下:在类的内部调用非静态方法命令时,是否也需要先声明一个对象呢?回答是:也是必须要先创建一个对象才能使用。通过的代码如下所示:上述代码中,可以看到,在好朋友的类中,定义了一个“调用”的方法,此方法中又创建了一个叫赵强的对象实体,由这个对象实体调用好朋友类的“说话”非静态方法。如何看待这种现象呢?可以将静态方法看作是此类的外部工具,表现形式如下:这样大家就易于理解为何可以在类的内部再创建他自己本身了。也就表明静态类实际上与类本身是无关的,而非静态类是依赖于类本身的。成员对于类的数据成员的理解,其实也是很简单的,我们只要把它看成是对象的“属性”就可以了。这个属性,就像是“好朋友”的姓名,衣服颜色一样的特征。在“易语言用户”类的开头,声明了一个“公开”的文本数据成员“姓名”,用于保存易语言用户的姓名。在“易语言用户”类的方法成员中调用了该数据成员的值,并利用控制台输出,这样就可以在有很多客户的情况下,区分我们正在与哪个用户进行交流。调用的代码:运行的结果如下:在“启动”方法中,声明创建了两个“易语言用户”类对象,“李文”、“张剑”,并分别给这两个对象的“小名”属性赋了值。如何区分是哪位用户有动作呢,就要通过用记的“小名”进行区分了。通过以上的简单讲解,相信大家对面向对象有个入门的了解,然后大家可以将上述代码中无用的控制台命令换成有用的程序代码,就可以实现面向对象的编程了。当然,继续了解了下的事物对编程更加有用。初始实际上“初始化”是一个特殊的类方法命令,类似于老易语言的“_初始化”子程序,希望你对老易语言中的面向对象有所了解。也就是说:当一个类的对象被创建时,“初始化”方法被自动调用;这个初始化方法可以不写,如果写了就会被首先执行,一般来说,这是用于对类的创建时的预置环境用的,相当于一个配置工具。我们用易语言不是也要配置一些东西,自己习惯的东西吗,致于您要配置什么,就根据需要写什么吧。我们选朋友时也是这样,需要一定的标准,适合的朋友才选择,不适合的朋友就选离,所谓“君子务本,本立而道生。”“初始化”必须是非“静态”的、非“私有”的、无返回值的类成员方法,可以没有参数或有多个参数,允许被重载。“静态初始化”方法必须是“公开”的、“静态”的、无返回值且无参数的类成员方法。 以上所有方法均可以被省略,如果被省略,易语言编译器会自动生成其默认实现。也就是默认有一个空的初始化方法存在,任务是什么也不做。编译器在编译具有基类的类的任一初始化方法之前,如果发现该初始化方法中不存在“调用其基类初始化方法的语句”,将自动在首部插入一条调用其基类默认初始化方法(即无参数的初始化方法)的语句,以确保基类的初始化方法被调用。 清理实际上“清理”是一个特殊的类方法命令,类似于老易语言中的“_销毁”子程序。也就是在类结结果束前进行一些清理的工作。比较安慰的是,易飞扬具有内存自动清洁功能,否则在这一步将要大家花费大量的时间进行内容的清理工作。如果大家不写这个类方法,默认是自动产生一个空的清理方法,当然是什么也不做啦。不过中国人交朋友都是有始有终的,也称之为善始善终。既然有出生、相遇,就有分别、死亡,这是万世不灭的道理。“清理”必须是“公开”的、非“静态”的、无返回值且无参数的类成员方法。系统在调用类的“清理”方法之后,总是会调用其基类的“清理”方法。这是一个递归过程,最终的结果是,该类的最基础类(系统.对象)的“清理”方法被最后调用。属性在成员中实际上已讲了一些属性的概念,那是成员属性,相当于老易语言中组件的属性。在此还要讲的是“属性方法”,在易语言的使用中,大家一定是非常羡慕组件中的属性不仅可以赋值,还可以读取吧,现在你也可以了。下面给出一个例子:在上述代码中,“易语言用户”类设置了一个“年龄”属性方法,用于返回属性值,第二个带有整数参数的“年龄”属性方法,用于接受属性的赋值。启动类中,读取属性的值,实质上是调用属性读取方法;对属性赋值,实质上是调用属性设置方法。怎么样,你也可以制作属性了吧。事件大家还记得在老版易语言中,那个按钮被单击事件,按钮被双击事件吗?这是大家很羡慕的一件事吧,您可能一直在想,怎么我做不了这种事件呢?从我的角度来看,这个就是一个特殊的方法,这个方法有特别的规定。看看下面一个事件子程序的代码:上述代码中,大家可以看到,在声明的部分,只是比普通的方法多了“事件接收”字样,在后面的参数中“被单击事件”去除事件两个字后,“_被单击”拿到了前面与组件相接,形成事件名称。在老版易语言中也是规定好的“_按钮_被单击”事件是固定不变的,如果变了就不起作用了,在这里也是这样的,如果不按规定写,就不会与事件的产生起作用了。换句话说,对组件的事件处理是通过匹配这些文本后进行相应的处理的。有个例子是说明了这个问题的。就是带窗口的计算器的例子,这个例子对每个按钮被按下的事件进行了处理。写到这里,提醒大家的事,这个易飞扬还没有完全成型,因此语法还在改之中,原来称“事件”,后改为“事件接收”,最新改为“事件处理”,这个大家要理解哦,每次更改都是为了精益求精。创建前面我的描述都是太简单了,现在开始,我还是要将正统的面向对象的概念介绍给大家。“重载”、“封装” 、“继承”和“多态”这些都是非常重要的。在面向对象中有一句老话:“万物皆对象”,这句话并不高深哦,有些类似于物理上常用的“万物都有原子组成”,哈哈,看到这里,大家也就可以理解了,如果想要编程的话,那么将所有操作的窗口、组件、单元都看成一个对象,然后对这个对象进行操作就好了呀,编程的思路会更加清晰的。创建其实前面例子中大家都用过了,类似于用“对象类的名字”后接空格和“你取的新生成对象的名字”后接“”等于号加上“创建”关键字及“对象类的名字”。白皮书中介绍的语法: 创建 类名称(参数表) 编译器将根据参数表自动搜寻并调用合适的“初始化”方法。 创建类的对象,会导致该类及其所有基类中的“初始化”方法被调用。最基础类(系统.对象)的“初始化”方法被最先调用,该类自身的“初始化”方法被最后调用。如果其中某个类有多个重载的“初始化”方法,编译器将根据规则选择其中之一调用。 示例: 对象 对象1 = 创建 对象;学生对象 张三 = 创建 学生对象(张三);销毁用户不需要关心对象何时被销毁以及如何销毁。这完全是“垃圾收集器”的工作。 在对象被销毁之前,其“清理()”方法会被系统调用。用户可在此方法中做一些处理,但这种需求并不多见。重载那么对于一个类中的方法命令,如果重名了,就是“重载”。这个问题的由来类似于中国人口那么多,那么叫“王强”、“赵军”的不计其数,这个就是重名了,但人还是不一样的,因为那么多人不可能是一个人吧。现在好了,在编程中,于一类的事物可以只取一个名字,而参数不同就可以进行处理了,这样不仅可以节约名称(有意义名字总有用完的一天),还可以让系统去自动根据参数的不同来进行处理。很强的功能哦。在一个类中,如果多个方法(不包括基类中的方法)具有“相同的方法名称和不同的参数形式”,那么称这个方法名称被“重载”。 “不同的参数形式”意味着:参数个数不同,或参数个数相同但“相同位置处有不同类型的参数”。 编译器将根据实际传入的参数形式选择调用匹配的重载方法。下面还是举个例子来说明的好。例如我们有两个名为“移动”的方法命令,参数不一样,一个方法只有一个参数是文本型,表示地点,另一个方法有两个参数是XY坐标。公开 类 启动类 公开 静态 启动 () 好朋友.移动(大连); 好朋友.移动(123,456); 公开 类 好朋友 公开 静态 移动(文本 地点) 控制台.输出行(移动到+地点); 公开 静态 移动(小数 坐标X ,小数 坐标Y) 控制台.输出行(移动到+坐标X.到文本()+,+坐标Y.到文本(); 运行结果如下:怎么样,厉害吧,易飞扬编译器生成的代码会自动处理一些事情的,有点智能化哦。实际上将“重载”理解为“重名”就好了。封装讲继承之前要讲到封装的。封装听起来很可怕,其实它什么也不是。就是将类装在一个盒子里,不可见,外国人以前称之为黑盒子,现在叫封装,换汤不换药而已。还记得前面说过的类中有不公开的私有成员吗?这个就是其他人不可见了,就称之为封装了。白皮书中是这样说的:类可以使用私有成员存储内部数据,可以使用私有方法对内部数据进行处理,可以通过公开或扩展的属性、方法、事件对外界提供操作接口,这些都是类的封装机制的体现。也就是你的好朋友自己有五脏六腹,不用你给他就有,他也不会给你看,因为这是他的隐私。但是他有衣服、名字等这些外在的东西你能看到,他会说话,这是他的公开的接口,虽然我们并不了解他的真实想法,这也是一种保护的方法。具体的例程看前面的没有公开属性的类方法命令就行了。继承父母的财产可以由孩子来继承,父母的基因可以传承给子女,传承后可能有些基本的没有改变,有些就有些改变了。下面是两个公开类,类名不一样,但是小汽车是个子类,他的父类就是汽车。汽车可以包含的子类很多,如公交车,卡车等。下面给出代码:公开 类 汽车 公开 移动(文本 地点) 控制台.输出行(移动到+地点); 公开 移动(小数 坐标X ,小数 坐标Y) 控制台.输出行(移动到+坐标X.到文本()+,+坐标Y.到文本(); 公开 类 小汽车 公开 移动(文本 地点) 控制台.输出行(安装火箭移动到+地点); 公开 移动(小数 坐标X ,小数 坐标Y) 控制台.输出行(安装火箭移动到+坐标X.到文本()+,+坐标Y.到文本(); 调用的代码为以下:公开 类 启动类 公开 静态 启动 () 汽车 奇瑞 = 创建 汽车; /汽车 奇瑞 = 创建 小汽车; 奇瑞.移动(大连); 奇瑞.移动(123,456); 大家可以看到,上述代码中如果将第一行的创建代码屏蔽,与将第二行的创建代码屏幕后的执行效果是不一样的。因为小汽车继承了父类汽车的两个方法,因此根据创建时的不同,运行效果也就不一样了。这个哪里运用最多呢?这样有什么好处呢?1原来,可以将一些类封装为类库,然后公开接口,如果你对某个类不满意,你就可以继承他的类,原始的类库不用更改。2也方便大型软件的共同开发,架构师将父类全部定义好,即使是空的没有代码的也无所谓了,然后由下面的工程师制作子类继承,将真实的代码写入。3改进软件也成为一件非常方便的事,如果某个类中的功能不适合使用了,需要升级了,就可以再一次地继承他,方便了程序的升级。多态多态实际上是与对象紧密相联系的。在类中,可以创建一个方法,如果这个方法中采用了对象作为参数,那么如果对象传递时是基类,那么就按基类进行处理,如果对象传递时是子类,那么就按子类进行处理。大家看下面的代码:公开 类 基类 公开 输出() 控制台.输出行(基类); 公开 类 子类 公开 输出() 控制台.输出行(子类); 上述代码中有两个类,一个是基类,一个是子类。那么都有相同的输出方法,且子类的输出方法覆盖了父类的输出方法。当创建不同的对象时,那么如果传递了这些不同的对象,就会按不同对象进行处理,代码如下:公开 类 启动类 公开 静态 启动() 基类 基类1 = 创建 基类(); 子类 子类1 = 创建 子类(); 测试多态(基类1); 测试多态(子类1); 静态 测试多态(基类 参数) 参数.输出(); 上述代码中,可以看到,加了一个“创建多态”的方法命令,而这个方法命令的参数是对象,因此当上述“启动”方法命令中创建了两个不同的对象,一个是父对象,一个是子对象,于是在调用“测试多态”的静态方法时,就根据不同的对象进行了不同的处理。接口“接口” 很简单,就是这样一种东西:就是空的方法组成的一个类,打包成类模块,然后供大家一起调用。这个类里的方法中,没有具体的代码,就是一个空的表,也可称之为接口表。类似于C语言中的头文件。接口具体的好处是在于多人工程开发时,由系统分析师制定出统一标准的接口,程序师进行具体接口程序的编程,这样大家在进行大型工程项目时就通过接口进行沟通了。使用“接口”时要注意以下几点:1接口只“声明”一个或多个“公开”的方法,但不提供方法的实现代码。也就是不需要系统分析师写代码。2定义接口方法时可以省略掉方法的“公开”属性,编译器默认其具有此属性。也就是说系统分析师可以偷一些懒了。写接口的格式样例如下:公开 接口 接口1 公开 接口方法1(); 公开 接口方法2();接口声明与类声明是同级别的。3只有类可以实现接口。一个类可以实现多个接口。一个接口可以实现多个方法。4接口文件编译为类库后,由系统分析师提交给程序师具体实现,不必提供类库的源文件。也就是说上述接口定义的代码保存为EF文件,然后编译为ECL文件,只要提供程序员ECL文件给他们编程就可以了。5接口类似一种“规范”,如果某个类实现了此接口,表明此类遵循了此规范,以后就可以按照这种规范的要求来使用此类。6当系统分析师提供类以后,由程序师来实现接口的具体代码时,要将此接口中的所有方法实现,一个也不能少哦,编译器会做严格的检查。一个类欲实现某个接口,意味着这个类“必须实现这个接口(及其所有基接口)中声明的所有方法”。7实现接口,就是由程序师具体实现原来接口表中空方法的代码。那么在定义类时,程序师需要将接口的信息告诉类。定义类时,通过“接口实现表”属性来指定该类所实现的接口,示例代码如下:类 类1 /指定单个已实现的接口 公开 接口方法1() /这里需要程序员添加具体实现代码 公开 接口方法2() /这里需要程序员添加具体实现代码 类 类2 /指定多个已实现的接口 /.上述代码中,类1指定了一个接口,类2指定了多个接口,具体的代码在接口方法中实现。上述的代码保存为EF文件后可以进行编译,在编译为EXE文件时,会检查ECL类库中的接口情况,如果正常,那么对于接口的调用就相当于对于类中具体实现代码的调用。接口通过“定义接口”、“实现接口”的两个步骤后,下面就可以进行“使用接口”了。定义接口是由系统分析师进行的工作,实现接口是由程序师进行的工作,一般大的项目就会这样安排,以利于分工合作,但是如果小的项目一般用不上,即使用上了,上述的也可能是一个人进行的。例如,在系统核心库中已有一个现成的接口,并且被编译为ECL类库,接口原代码可能为以下形式:(定义接口)公开 接口 错误处理 公开 逻辑 处理错误(整数 错误码, 文本 错误文本);实现接口的代码可以写成以下内容:公开 类 错误处理类 公开 逻辑 处理错误(整数 错误码, 文本 错误文本) 控制台.输出行(哈哈,系统运行时错误被我捕获!); 控制台.输出(错码码); 控制台.输出行(错误码); 控制台.输出行(错误文本); 返回 真; 调用接口的代码可以为以下形式:公开 类 启动类 公开 静态 启动() 控制台.输出行(测试中); 错误处理 自定接口 = 创建 错误处理类; 运行环境.置错误管理器(自定接口); 对象 对象1; / = 创建 对象(); 控制台.输出行(对象1.到文本(); /故意使用 空 对象 当调用接口的方法时,就相当于调用了具体对象实现的方法。其中有两行大家要注意: 错误处理 自定接口 = 创建 错误处理类; 运行环境.置错误管理器(自定接口);上述代码中可以看到,“错误处理类”对象被声明到“错误处理”这个接口中,然后下面一行对接口的操作实际上就是对对象的操作。总结大家也可以先学习旧版易语言中的面向对象,等熟悉之后,再学习易飞扬就非常轻松了。对比如下:面向对象因素VB易语言易飞扬构造/初始有有有析构/清理有有有继承不支持有有虚拟方法不支持有有多态不支持有有封装有有有重载/重名无无有接口无无有易语言中的面向对象教材可以通过学习易语言编程系统第十八章,或“易语言知识库ESDN资料手册开发手册易语言面对对象编程”中可以找到。看教材的目的就是要实用,那么上述用了好朋友进行比喻,如果应用到实际程序中将会如何呢?你要将你的数据库系统用分类的方法进行分门别类,如菜单类,快捷键类,数据库操作类这样,一个具有人性化的程序就会出来了,里面的命令程序只要按面向对象的方法调用就行了。好了,大话面向对象到此暂告一段落,希望通过这些小小的比喻大家能了解掌握面向对象的知识,逐步看一些大一些的面向对象的例程,看的时候大家可以将这些大例程中的对象用概念图画出他的层次结构,互相之间的继承关系,以这样的方式对对象进行研究,这样基本上就能看明白了。最后要告诉大家的是,我还会写更多的教材和练习给大家看,毕竟在大量的练习下才会有长足的进步。面向对象并不难,细细品味易飞扬,道法自然是根本,编程世界谁称王!第8章 易语言的子程序本章主要介绍易语言子程序的创建和调用、子程序参数的使用以及参数属性的设置方法。本章学习内容:8.1 新建子程序 8.6 参数的参考属性8.2 调用子程序 8.7 子程序的返回值8.3 两类子程序的区别 8.8 课后练习8.4 子程序参数 8.5 参数的可空属性将程序分割成较小的功能单元就可以简化程序设计任务,这些功能单元被称为子程序,可以把共享的或常调用的功能置于子程序中,达到简化程序设计、方便代码重用和提高程序维护效率的目的,这是结构化程序设计的主要特征之一。 子程序可把程序划分成相对独立的功能单元,每个单元都比无子程序的整个程序容易调试和理解; 一个应用程序中的子程序,往往不必修改或只需稍作改动,便可以成为另一个程序的子程序。8.1 新建子程序下面我们就开始新建第一个自定义子程序。方法十分简单,一步一步跟我来吧!首先在启动窗口添加一个按钮,默认名称为“按钮1”。双击按钮1进入代码编辑界面。另一种更快捷的方法是,在代码编辑区获得焦点时,同时按下“Ctrl 键”和“N键”,也可以新建子程序。将光标移到代码编辑行,右键单击,在弹出菜单中选择“新子程序”命令,就可以新建子程序。新建子程序的默认名称为“子程序1”,依此类推。第三种方法,到主菜单上。选择“插入” “新子程序”命令也可新建子程序。“子程序1” 已经存在,当另一个子程序被修改成“子程序1”时,易语言弹出出错提示。注意:在同一个程序集中,子程序名不能重复。特别在修改的时候,易语言会提示并修改已经被使用过的名称。被易语言修改的子程序名。新建的子程序没有参数,这需要操作者自行添加所需数目的参数并设置参数的类型以及参数的可空、参考和数组等属性。特别应该注意的是,每个新建的子程序都不会被易语言或其它子程序自动调用,下面将讲解如何调用子程序。8.2 调用子程序前一节中讲了如何建立子程序,下面演示如何调用一个子程序。在“_按钮1_被单击”事件子程序中添加程序代码 “ 子程序1() ”或直接复制名称,将其粘贴过来。在“子程序1”中添加代码:信息框(“你好!我是信息框。”,#信息图标,) 同一个子程序可以被多次调用。在“按钮2”事件子程序中添加代码 子程序1() 。 按F5键运行程序,分别单击“按钮1”和“按钮2”,都能弹出“子程序1”里的信息框。一个子程序可以在事件子程序和其它新建的子程序中多次被调用,也可以被其它程序集的事件子程序和新建的子程序调用。要注意的是,在本程序中定义的子程序只能在本程序中使用。每次调用子程序时,子程序中的所有命令都将从第一条开始顺序执行,当执行到子程序尾部或者遇到“返回”命令时即返回到调用此子程序命令的下一条命令处。这里的“子程序1”同时被修改为信息框子程序。把“子程序1”修改为“信息框子程序”。上节中提到了子程序名称的问题,这里我们还要提一个小建议。当要修改一个子程序名称时,应该直接到这个子程序的定义位置进行修改。这样可以使调用它的程序代码同步修改该子程序的名称,如上图所示。这可以避免因调用无效子程序导致的编译错误。 大家可以看到,子程序必须由其它子程序调用才能被执行。子程序的调用方法与命令的调用方法完全一致。 8.3 两类子程序的区别虽然新建的子程序(自定义子程序)和事件子程序的调用方法一样,但它们之间也有一些不同之处。输入参数名称并设置类型。最后按F5键运行程序,单击“按钮1”,信息框不见了。这是“_按钮1_被单击”子程序的原型,没有参数。光标选中子程序名称,按Enter键添加一个参数。信息框看不到的原因是“_按钮1_被单击”子程序参数结构被改变,易语言就会把它当作新建的子程序,和“按钮1”没有任何联系了,而新建子程序可以任意的添加参数。请大家自行总结一下新建的子程序和事件子程序的区别。8.4 子程序参数 参数和变量的使用方法一样,可以使用赋值语句在参数内临时存储数据。参数有参数名(用来在程序中引用一个参数)、数据类型(确定参数能够存储数据的种类)以及“可空”和“参考”等属性。参数只能在定义它的子程序中使用,相当于局部变量。把8.3中“_ 按钮1_被单击”事件子程序的“参数1”删除。参数的“类型”属性可为空。如果空,默认为整数型。在“信息框子程序”添加两个文本型参数“参数1”和“参数2”。按F5键,程序无法运行,在输出面板中可以看到出错提示。这就说明我们还要在调用上述子程序时提供具体的参数。用光标选中此行并双击,在括号内添加“,”号,按Enter键。看到了吗?调用子程序的命令前多了个“”号,我们可以将它展开。展开的方法:直接双击或用键盘上的右光标键。标签的标题在此处设置。参数提示和实际参数的内容是互相对应的,在上面添加文本型数据“易语言”,当程序运行时,下面“参数1”保存的数据就是“易语言”。接下来我们在程序中为子程序提供具体的参数数据。用“Ctrl+Tab”组合键切换到界面设计状态,在窗体上添加两个标签和两个编辑框,并将标签的标题属性设置为“输入123”,提示用户。这是前面提到的“按钮1”,下面的是“按钮2”。切换到代码编辑状态,在子程序调用处,分别为两个参数提供数据(编辑框提供的文本型数据)。修改“信息框子程序”代码。按F5键运行程序,在“编辑框1”和“编辑框2”中输入“123”,单击“按钮1”,第一个信息框被弹出。你也可以输入其它的数据,看一看效果。子程序如需要接收参数数据,必须先在子程序定义处的参数表部分定义所需的参数。调用有参数的子程序时所传递过来的数据将被顺序地填入对应的参数中。如果传递过来的数据与对应位置处的参数数据类型不一致,在可以互相转换时,系统将自动将传递过来的数据转换成对应参数的数据类型后再赋值给该参数;如果不能转换,就会产生运行时错误。如上面的第 2 步在调用子程序的同时就把“编辑框1.内容”和“编辑框2.内容”作为参数数据对应地传递到了编辑框子程序内的两个参数“参数1”和“参数2”内。 8.5 参数的可空属性参数可空,就是说该参数是可选的,从字面上就能理解它的意思。就是在调用子程序时,可以不提供该参数所需的数据。看看下面的例子。将“参数2”可空属性选中。方法是,选中该处单元格再单击或选中后按空格键。把调用处的“参数2”删除。如果某个参数的“可空”属性为真,那么在调用本子程序时,可以不给此参数传递数据。可空的参数主要用于支持具有默认值的参数;另外,如果给某个子程序添加了新参数却又不想去更改以前调用此子程序的代码,那么只要将新参数设置为可空参数就行了。8.6 参数的参考属性打个比方,你家的门锁有两把钥匙,分别由两个人拿着。不管是哪一个人都可以打开房门,改变家里家具的摆放位置。如果子过程的参数具有“参考”属性,那么,当调用子程序时负责提供该参数数据的是一个变量的话,在子程序中修改了该参数的值,那个变量的值也会跟着被改变。在“_按钮1_被单击”事件子程序中添加两个局部变量。把编辑框提供的文本型数据转换到整数型。注意:文本型数据默认具有参考属性,所以此例中为了演示参数的参考属性,把文本型数据转换到整数型。添加信息框,显示调用子程序后,“变量2”的值。将“信息框子程序”两个参数的类型改为整数型。添加代码,修改“参数2”的值。注意:为了更好地了解程序的运行过程,可以通过在关键代码行前设置断点的方法来跟踪代码行的执行情况。在代码行前设置断点。设置断点的方法:用光标选中将被设置断点的代码行,再按F9键。按F5键运行程序,在启动窗口的编辑框中输入“123”,单击“按钮1”。窗口消失,程序停止,一个断点变黄。这就说明在“_按钮1_被单击”事件子程序中,第一个断点处的“信息框子程序”将被执行。“参数2”的值被改变。“参数1”的值是“变量1”的值。两个条件都成立。再按F5键,“信息框子程序”里的代码被执行。说明子程序已经被调用。再按F5键,断点变为红色,弹出条件成立的信息框。单击“确定”按钮。程序又跳到了“信息框子程序”被调用处的下一行代码处,说明“信息框子程序”执行完毕。再按F5键,弹出“_按钮1_被单击”事件子程序中的信息框。由于运行开始时“编辑框1”内的数据为空文本,转换到整数后为“0”。即使“参数2”的数据被改变,“变量2”仍保存原值。“参数2”没有设置参考。单击“确定”按钮,代码运行结束。关闭程序,然后设置“参数2”的参考属性,设置“参数2”的参考属性的方法类似可空属性的设置,在参数定义表“参考”栏相应空格内单击使之出现一个“”号。按F5键运行。最后信息框显示“变量2”的值和“参数2”的值是相同的。 当使用变量向子程序的参数传递数据时,如果所传递过来的变量为数组、用户定义数据类型、库定义数据类型、字节集型或文本型,则无论参数的“参考”属性是否为真,都将是传递变量的指针(即该变量的内存地址),这样在子程序中改变该参数的值时相应变量的值也会被改变;如果所传递过来的变量类型与相应参数的数据类型不一致但可以相互转换,譬如将整数型变量传递到小数型的参数时,则在数据被实际传递前,系统将首先自动将整数型变量的值转换为小数型数据,然后再进行传递,在这种情况下,即使参数的“参考”属性为真,系统也无法传递指向原变量的指针,只能传递经过类型转换后的变量的值。如果系统将数据指针成功地传递过来,那么在子程序中对此参数内容的更改将会相应地反映到调用子程序时负责提供相应参数数据的变量上。8.7 子程序的返回值子程序可以返回数据,称为返回值,但必须首先定义返回值的类型,并且要在子程序中使用“返回”命令进行返回。将“信息框子程序”的返回值类型设置为整数型。删除下面两行代码。参数2 123信息框 (“参考的使用方法。” #换行符 “变量2=” 到文本 (变量2), 0,)在“_按钮1_被单击”事件子程序中添加名称为“返回值”的整数型变量。“返回值”变量用来保存“信息框子程序”返回的整数型数值。在“信息框子程序”的每个分支处添加返回命令。将“信息框子程序”里的两个“信息框”命令复制到“_按钮1_被单击”子程序的判断语句中。最后按F5键运行程序。调用一个子程序时,子程序中的所有命令将从第一条开始顺序执行,当执行到子程序尾部或者遇到“返回”命令时即返回到调用此子程序命令的下一条命令处。当一个子程序有返回值时,如果需要使用该返回值,可以把子程序调用命令嵌在其它命令中,如“变量1=变量2+子程序名(参数)+变量3”(这里假设“子程序名(参数)”有返回值),也可以建立一个与该返回值数据类型相同的变量来接收该返回值,即使用“变量名=子程序名(参数)”的形式(“=”在这里是赋值号)。8.8课后练习(1)练习子程序的建立与调用。 新建“Windows窗口程序”添加一个按钮。添加如图上的代码。完成后运行一下程序看看。这两个地方添加什么值,才可以使程序运行,并且能够正确显示呢?请大家来将这两个命令补充完整。(2)练习编写用子程序的方式表示两数相加,返回和的例程。 ,新建易程序,放两个编辑框组件与一个按钮组件,双击按钮组件,进入程序代码界面。新建一个子程序,名称为:“和是几”。加入两个数。参数类型为整数型。返回值类型为整数型。在“_按钮1_.被单击”事件子程序下输入以下程序代码:信息框 (和是几 (到数值 (编辑框1.内容), 到数值 (编辑框2.内容), 0, )在“和是几”子程序下输入以下程序代码:返回(数1+数2)最后按F5键运行程序看看。(2)用子程序的方式编写判断两个数大小的程序,并返回最大数。 新建易程序,放两个编辑框组件与一个按钮组件,双击按钮组件,进入程序代码界面。在“_按钮1.被单击”子程序下输入以下程序代码:信息框 (和是几 (到数值 (编辑框1.内容), 到数值 (编辑框2.内容), 0, )在“和是几”子程序下输入以下程序代码:如果 (数1 数2) 返回 (数1)否则 返回 (数2)如果结束最后按F5键运行程序。大家再留意一下,“如果”命令还有这种形式的,这种形式的“如果”命令虽然占的代码行稍多,但逻辑很清晰,提倡大家以后在使用“如果”命令时多使用这种形式。新建一个子程序,名称为:“谁最大”。加入两个数。参数类型为整数型。返回值类型为整数型。第2章 编程的基础概念在本章中,将讲到编程的一些基础知识,包括变量的概念,变量的有效范围,数据类型等知识。其后,本书将引导您编写一个自己的MP3播放器,认识窗口、按钮、编辑框三个常用组件以及命令及事件子程序。本章学习内容:2.1 编写第二个程序 2.6 编写一个MP3播放器2.2 什么是变量与常量 2.7 认识窗口、按钮、编辑框2.3 变量的数据类型 2.8 认识事件子程序2.4 变量的有效范围 2.9 认识组件的方法2.5 变量的初始值 2.10 课后练习大家会说1+2等于几太简单了,这个例程虽然简单,但这是为以后进行复杂一些的计算作准备,所以我们先用最简单的例子来演示,大家只要学会写这个小程序,再遇到复杂一些的计算,就可以自己写了。那么如何用易语言实现1+2的计算呢,大家就跟着下面的步骤来吧。2.1 编写第二个易程序首先启动易语言。点击“编辑框”组件。用鼠标在窗体上拖动画出一个编辑框组件。名称为“编辑框1”。点击“按钮”组件。在窗体上拖动鼠标画出一个按钮组件。名称为“按钮1”。在属性面板中找到按钮的标题属性,将标题内容改为“计算1+2=?”。大家可以看到按钮组件的标题被更改了,大家再双击按钮组件,进入程序代码设计界面。大家可以看到系统已自动生成一个名称为“_按钮1_被单击”的
展开阅读全文