面向对象程序设计教案Word格式.docx
《面向对象程序设计教案Word格式.docx》由会员分享,可在线阅读,更多相关《面向对象程序设计教案Word格式.docx(97页珍藏版)》请在冰豆网上搜索。
面向对象程序设计范型主要特征:
程序由对象和消息组成,可用公式表示成:
程序=对象+消息;
支持面向对象程序设计范型的语言有C++、Java、C#等。
其中C++不仅支持面向对象程序设计范型,同时也支持面向过程程序设计范型,是一种混合型语言。
1.1.2面向对象程序设计的基本概念
基本概念是理论基础,与具体的程序设计语言无关。
☺对象
对象这个词语在我们日常生活中是一个使用频率很高的词,在现实生活中对象无处不在,如我在教室里给同学们上课,这里面就有很多对象,我就是一个对象,是一名教师,同学们也是对象,课也是对象,教室同样是对象。
大家有没有发现在这句话里所有的名词都是对象。
抽象的东西同样也是对象,可以说任何事物都是对象,在面向对象程序设计范型中的对象是对现实生活中对象的一种模拟,在面向对象程序设计范型中,对象是描述属性的数据和对属性数据施加的一组操作的统一体。
举个例子,张三是我们班的一名同学,那么对象属性有学号、姓名、成绩等,对象操作有看书、写字等。
☺类
在现实世界中,类是对一组具有相同属性和行为的对象的抽象,如张三、李四都是人,都具有相同的生理构造和相同的行为方式。
类和对象之间的关系是抽象与具体的关系,对象是类的一个实例。
这种关系和C语言中的数据类型与变量的关系并没有什么两样。
如inta,b;
int是一种数据类型,a,b是两个不同的变量,a,b具有相同大小的存储空间及相同的加减乘除操作,都是整型变量。
在面向对象程序设计范型中,类是对具有相同数据结构和相同操作的一类对象的描述。
在C++语言中,数据称为数据成员,操作是用函数来完成的,称为成员函数。
在用面向对象程序设计语言描述类与对象时,总是先声明类,再由类来生成该类的对象。
可以说类就是生成对象的数据类型,只不过这个数据类型是用户自定义的数据类型。
有点类似于C语言中的结构体,只不过C语言中的结构体只有数据而没有操作。
假设Person是一个已经声明好的类,大家比较一下下面两条语句:
Personp1,p[10];
inti1,i[10];
这两条语句是不是很相似呢?
☺消息与方法
现实世界中各对象之间互相联系,互相作用,如我给大家讲课,同学们有在听课的行为。
同样在面向对象程序设计范型中对象之间也是互相作用的称为对象的交互。
对象之间的交互是通过消息传递的机制来完成的,发送消息的对象是消息的发送者,接收消息的对象是接收者。
就讲课这个例子来讲,教师讲,学生听,教师是消息的发送者,学生是消息的接收者。
在具体的实现面向对象程序设计范型的语言中,向某个对象发送消息是通过调用该对象的成员方法(函数)来实现的。
消息与方法的关系是:
对象根据接收到的消息调用相应的方法,反过来,有了方法,对象才能响应相应的消息。
1.1.3面向对象程序设计的基本特征
面向对象程序设计方法具有4个基本特征:
☺抽象
抽象是对具体事物的共性的一个归纳,在抽象过程中通常忽略与当前主题无关的方面,是对复杂世界的简单表示。
如在学生成绩管理系统中,我们只关心学生的学号、姓名、成绩等数据而忽略其身高等数据,而在学生健康管理系统中,身高数据是必须的,相反成绩等数据就不重要了。
在面向对象程序设计中的抽象包括数据的抽象和行为抽象,抽象的结果就是声明了一个类型。
在C++、Java、C#等语言中,这种类型就是类(class)。
类是对象的抽象,而对象是类的实例。
在Personp1,p[10];
语句中Person就是一个类名,而p1是一个对象,p是一个含有10个对象的对象数组,每个对象都有Person类的属性和行为。
在面向对象程序设计方法中,对一个具体问题的抽象分析的结果就是通过类来描述和实现的。
如在学生成绩管理系统中,对所有学生进行归纳、分析,抽象出其中的共性,可以得到:
共同的属性:
学号,姓名,成绩。
共同的行为:
录入成绩、修改成绩、输出成绩等。
☺封装
在现实世界中,封装就是包装,使外界不知事物的具体内容。
在面向对象程序设计中,封装就是把数据和操作代码集中起来放在对象内部,尽可能隐藏对象的内部细节。
使用一个对象时,只要知道它向外界提供的接口而无需知道它的数据结构细节和实现操作所使用的算法。
如我们看电视,只要知道开机,换频道和调声音就行了,没必要知道电视机的内部结构和工作原理。
电视机上的几个按钮就是对人们提供的接口。
封装的好处是将对象的使用者与设计者分开,隐藏了复杂性,提供了代码的复用性,从而大大提高了软件的开发效率。
封装性是面向对象程序设计中一个重要特性,该特性有利于数据安全。
如电视机和电脑的机壳保护了里面的元器件一样。
☺继承
继承体系了各相关类之间的“是一种”的关系,如狗是一个哺乳动物。
就是说狗类继承了哺乳动物类的所有特性。
继承使类之间具有层次关系。
若B类继承类A,则类B包含了类A的数据和操作,同时也可加入自己所特有的新的数据和操作。
这时A类称为父类或基类,B类称为派生类或子类。
类B是从类A派生的。
面向对象程序设计提供的继承机制的作用有两个:
一是避免公用代码的重复开发,二是通过增加一致性来减少模块间的接口。
继承机制很好的体现了“软件重用”的思想,通过继承,派生类可以重用已有软件中的一部分甚至大部分,只需要在派生类中描述基类中没有的数据和操作,大大节省的编程的工作量,同时,派生类还可以覆盖、修改或重新定义基类中的操作。
继承从基类个数的多少可以分成单继承与多继承。
C++支持多继承,但Java却不支持。
单继承指基类只能是一个,而多继承中基类至少有两个。
多继承容易产生歧义。
☺多态
面向对象程序设计中的多态是对现实世界中多态的一种模拟,如学生学习这个现象,不同学生的学习方法是不一样的,如小学生的学习主要是死背,而大学生的学习主要使用的是理解记忆。
面向对象程序设计中的多态性是指不同对象接收到相同的消息时执行不同的操作。
如对于众多的形状类对象都有求面积的方法,但不同的形状对象求面积的公式是不一样的。
C++语言支持编译时的静态多态性和运行时的动态多态性,分别是通过函数重载和虚函数来实现的。
多态性增加了软件的灵活性和通用性,允许用户建立明确、易懂的通用软件。
1.2为什么要使用面向对象程序设计
1.2.1传统程序设计方法的局限性
传统的程序设计是面向过程的结构化程序设计,其局限性至少表现在以下几个方面:
☺生产效率低下
自第一台计算机问世以来,计算机硬件水平在突飞猛进的发展,而软件的生产能力还是比较低下,体现在开发周期长,效率低,费用高,曾经出现了所谓的“软件危机”。
在面向对象程序设计出现之前,人们一直采用结构化的程序设计来解决问题,其主要思想是面向过程的,即功能分解并逐步求精。
如Pascal语言和C语言都集中体现了这种结构化的设计思想。
这种采用结构化思想的软件构造方式,缺乏大粒度、可重用的构件,软件的可重用问题没有得到很好的解决。
同时随着软件规模越来越大,结构化程序的数据和操作分离的特性使得软件的维护与更新变得几乎不可能,严重时软件必须重写。
传统的程序设计方法很难解决软件的重用性、复杂性和可维护性问题。
☺难以表示复杂的信息类型
随着软件规模的增大,采用传统的程序设计方法的语言需要有更大的信息表示与处理能力,但这是面向过程的程序设计语言所不具备的。
☺难以适应新环境
难以适应并行处理、分布式、网络和多机系统等新的程序运行环境。
总之,传统程序设计方法难以满足软件开发的需要。
面向对象程序设计方法由此应运而生,很好地解决了上述面向过程的程序设计方法的局限性。
满足了软件开发的需要。
1.2.2面向对象程序设计方法的优点
☺提高了程序的重用性
面向过程程序设计的重用性体现在标准函数库的使用上,只提供了非常基本的功能;
而面向对象程序设计的重用性体现在类库上,类库中的类不仅可以直接使用,而且可以在类库中类的基础上派生新类,对基类进行扩充和修改以满足应用需求,极大的提高了程序的重用性,因此有人将类称为“软件IC”(软件集成电路)。
☺有效控制了程序的复杂性
面向过程程序设计数据与操作相分离,控制程序的复杂性是程序员沉重的负担,而面向对象程序设计采用封装与信息隐藏技术,将数据与操作放在一个类中形成一个不可分割的整体,有效的控制了程序的复杂性。
☺改善了程序的可维护性
面向过程程序设计方法生产出来的软件很难维护,是软件危机的突出表现,而面向对象程序设计方法产生的软件则容易维护,只要类接口没有改变,类里面的数据表示和操作的实现可作随意修改。
比如电视从模拟电视变成了数字电视,但只要遥控器没有变,我们仍然可以很方面的看电视。
同时,面向对象程序设计中的封装机制使非法操作成为不可能,大大减少了程序的出错率。
☺更好的支持大型的程序设计
面向对象程序设计采用类作为基本的软件模块,更好地支持大型的程序设计,可将一个任务系统进行分工,每个程序员可以独立设计,测试自己负责的模块。
☺增强了计算机处理信息的范围
面向对象的程序设计更接近人类的思考方式,更容易描述、抽象现实世界,实际上是大大增强了计算机处理信息的范围。
☺能很好适应新的硬件环境
面向对象程序设计中的对象、消息传递等思想和机制与分布式、并行处理、多机系统及网络等硬件环境正好吻合,容易在这些平台上开发软件。
总之,面向对象程序设计解决了面向过程的程序设计的所有局限性。
是软件开发史上一个重要的里程碑,现代的程序设计语言几乎都是面向对象的程序设计语言,都是采用面向对象的程序设计范型。
1.3面向对象程序设计的语言
☺C++
☺Java
☺C#
第2章C++概述
【教学目的与要求】要求学生了解C++语言的特点,熟练掌握C++源程序的构成;
牢记C++在非面向对象方面对C的扩充。
【重、难点】重点是C++程序的构成;
难点是C++在非面向对象方面对C的扩充。
【教学时数】6
【教学方法】讲授与演示相结合,以演示为主。
【实验项目】C++编程入门练习
【习题】教材课后习题2.2,2.4,2.18,2.19,2.20,2.22
2.1C++的起源和特点
2.1.1C++的起源
C++是从C演变而来的,最初被称为“带类的C”,C++经过20多年的发展,至今仍是一种充满活力的程序设计语言。
C++继承了C语言原有的高效性、灵活性精髓,扩充了面向对象机制,弥补了C语言不支持代码重用、不宜作大型软件的开发等不足,成为一种既支持面向过程程序设计又支持面向对象程序设计的混合型程序设计语言。
2.1.2C++的特点
☺C++全面兼容C,是C的超集
☺全面支持面向对象机制
2.2C++源程序的构成
2.2.1一个简单的C++程序
//sum.cpp
#include<
iostream>
usingnamespacestd;
intmain()
{
intx,y,sum;
cout<
<
"
Pleaseinputtwointeger:
'
\n'
;
cin>
>
x;
y;
sum=x+y;
x+y="
sum<
endl;
//endl是换行操作符
return0;
}
上面的程序是用标准C++写的,可以看出C++程序与C程序非常类似,只不过可进行行注释,采用了新的头文件形式,在输入输出上采用预定义的输入输出流对象。
2.2.2C++程序的结构特性
上例只是一个简单的C++程序,并没有体现面向对象程序风格,一个真正的面向对象程序由类的声明和类的使用两大部分组成。
后面我们将出逐步给出能运行的C++程序,本章主要讲C++在非面向对象部分对C语言的扩充。
2.2.3C++程序的编辑、编译、连接和执行
开发C++程序的过程通常包括编辑、编译、运行和调试等步骤,有很多集成开发平台可以帮助我们完成C++程序的开发,例如最常见的VC++6.0,本课我们就使用这个开发平台。
大家在学习C语言的时候用的什么平台,我在给09网络上C课程时用的就是这个集成化的开发平台。
采用的是Win32ConsoleApplication的工程类型,如果大家学习C时也是用VC6,对它应该不会陌生。
若没有使用,则应该查阅本书的上机指导书。
2.3C++在非面向对象方面对C的扩充
C++是C的超集,所有C语言的语句依然可以在C++中使用,C++不仅增加了面向对象机制,而且在非面向对象方面也增加了一此新的特性。
2.3.1行注释
行注释的符号是//,顾名思义,行注释用来对一行的语句进行注释。
C语句的注释方法在C++中仍可使用,主要用于语句块的注释。
2.3.2C++的输入输出
用cin来从键盘接收数据,用cout来向显示屏输出数据,同时C语言中的printf和scanf两个函数也是可以在C++中使用的。
只不过C++的输入输出更容易使用。
下面再给出两个使用cin和cout的示例。
charname[20];
inputyourname:
name;
Hello,"
name<
这个示例非常简单,从键盘上接收名字,然后输出一个招呼。
C++输出数值时采用的默认数制是十进制,如果想用八进制或十六进制输出数值时,则要用到操纵符oct或hex。
示例如下:
intx=25;
hex<
x<
"
dec<
oct<
8<
大家思考一下,在输出8时,结果又是什么呢?
2.3.3灵活的局部变量声明
在C++中,允许变量声明与可执行语句在程序中交替出现,这在C语言中是不允许的,除非使用语句块。
C++允许变量在使用前在任意位置定义,极大提高了程序的灵活性。
当然也可采用C语言的定义形式,到底采用哪种形式,一个合理的建议是:
在大函数中,在最靠近使用变量的位置声明,而在较短的函数中把变量集中在函数开始处说明较好。
下面给出一个C++中能用但在C中出错的程序示例。
//演示C++局部变量的定义
inti=25;
i<
intj=30;
j<
2.3.4结构名、联合名与枚举名可直接作为类型名
在C++中,结构名、联合名、枚举名可直接作为类型名,而在C语言中必须给出全名。
示例程序如下:
intmain(intargc,char*argv[])
enumSex{female,male};
Sexs1=female;
s1<
2.3.5const
C++中,可用const关键字定义常量,完全可取代C中的#define预编译指令,它消除了#define的不安全性。
但两者有本质的区别,#define是完全的宏替换,在预编译阶段完成简单替换,定义的符号不占用内存空间,没有数据类型。
而const定义的常量是占用内存空间而且有数据类型的。
下例演示了const取代#define的好处及#define的不安全性。
inta=1;
#defineT1a+a
#defineT2T1-T1
T2is"
T2<
}//例2.5
程序结果是2,这个答案是错误的,本意是想输出0。
constintT1=a+a;
constintT2=T1-T1;
}//例2.6
结果是0,完全正确。
const也可与指针一块使用,它们组合使用情况较复杂,可归纳为三种:
☺指向常量的指针变量:
如constchar*name=”Zhang”;
☺指向变量的常指针:
如char*constname=”Zhang”;
☺指向常量的常指针:
如constchar*constname=”Zhang”
大家参考下面的示例程序:
chartmp[80]="
China"
//指向常量的指针变量
constchar*name=tmp;
//此句不对name[3]='
L'
name="
Li"
//指向变量的常指针
char*constname1="
Wang"
//此句也不对,教材错了,在初始化时Wang在常量区name1[3]='
//可进行如下修改
char*constname2=tmp;
name2[3]='
name2<
//指向常量的常指针
constchar*constname3=tmp;
//此句不对name3[3]='
T'
//此句也不对name3="
ok?
从上例可以看出,使用const可以进行更严格的检查。
2.3.6内联函数
在函数说明前加上关键字“inline”,就表示该函数是内联函数,可使C++编译器将函数体中的代码插入到调用该函数的语句处,同时用形参取代实参,而不会执行函数调用,是一种用空间换时间的措施。
通常只有在规模很小而且使用频繁的函数才定义为内联函数,内联函数与带参宏定义有很大区别。
内联函数的使用及其与带参宏定义的区别可见下面三个示例程序。
//演示内联函数的使用
inlineintbox(inta,intb,intc)
returna*b*c;
inta,b,c,v;
a>
b>
c;
v=box(a,b,c);
a*b*c="
v<
//演示带参的宏定义,可能带来的副作用,即错误
#definedoub(x)x*2
for(inti=1;
4;
i++)
cout<
doubleis"
doub(i)<
1+2doubledis"
doub(1+2)<
//此处结果错误
用内联函数可以消除宏定义带来的不安全性,不会出现错误,因此,在C++中建议不用宏定义而用内联函数。
如下示例程序。
inlineintdoub(intx)
returnx*2;
voidmain()
doubledis"
2.3.7带默认参数的函数
C++允许在定义函数时,给出部分参数的默认值,具体的定义形式见如下程序示例,相关说明见教材。
intsum(inta,intb,intc=10)
returna+b+c;
sum(1,2)<
sum(1,2,3)<
2.3.8函数的重载
所谓函数重载就是允许函数名相同而参数类型或个数不同。
这在C语言中是不允许的,C++中,当两个或多个函数共用一个函数名时,称为函数的重载。
函数重载的好处是极大的减少了重复代码量。
参考如下两个函数重载的示例。
注意函数重载与默认参数不要一起使用,否则会出现程序歧义性错误。
intsquare(inti)
returni*i;
longsquare(longi)
doublesquare(doublei)
inti=12;
longj=1234;
doublek=4.67;
*"
="
square(i)<
cou