1、本讲主要内容:面向对象的基本思想 类和对象概念及举例 属性和方法 类成员的访问控制 构造函数和析构函数 封装、继承、多态 面向对象技术的由来 面向过程的设计方法(结构化程序设计方法)的不足:功能和数据分离,不符合人们对事物的认识,难以保证数据和功能的相容性 基于模块的设计方法,使软件修改困难 自顶向下的设计方法,限制了软件的可重用性,降低了开发效率,维护困难面向对象设计方法 把数据和对数据的操作作为一个相互依赖不可分割的整体,符合人们的思维习惯 采用数据抽象和信息隐蔽技术,使问题简单化 有助于控制软件的复杂性,提高软件的生产效率其他程序设计方法 面向过程的设计方法:在科学计算中仍有其优势 面向
2、逻辑的设计方法:人工智能 面向规则的设计方法:专家系统类 类是对象的符号表示形式。类描述组成对象的属性、方法和事件等。类通常同时包含定义和实现,但它也可以包含没有实现的一个或多个成员。类的概念类似于面向过程程序开发中的数据类型(结构)概念。C+类声明class Rectangleprivate:int a,b;public:int Square()return a*b;int Girth()return 2*(a+b);void Assign(int x,int y)a=x;b=y;1)定义了一个类,名为Rectangle2)类中包含了两个私有成员(属性)a,b,分别为长方型的长和宽。3)类中
3、包含了三个成员函数(方法),分别计算长方形的周长、面积和为a,b赋值。4)private表示a,b只能在类内部使用。5)public表示表示三个函数可以在类外被调用 类类Rectangle包含了长方形的静态特征长和宽,类似结包含了长方形的静态特征长和宽,类似结构,还可以包含更多的属性,类型可各不相同。构,还可以包含更多的属性,类型可各不相同。类类Rectangle也包含了长方形的行为特征(成员函数),也包含了长方形的行为特征(成员函数),周长和面积的计算。周长和面积的计算。类中的方法可以在类外定义,如:类中的方法可以在类外定义,如:class Rectangleprivate:int a,b;
4、public:int Square();int Girth();void Assign(int x,int y);int Rectangle:Square()return a*b;int Rectangle:Girth()return 2*(a+b);void Rectangle:Assign(int x,int y)a=x;b=y;对象object 类描述对象的“结构”,而对象则是类的可用“实例”。每个实例都是其类的一个精确而又不同的副本。所以创建对象的动作就称为“实例化”。一个类也可以用于根据需要创建多个对象。类也可以通过封装来控制用户对对象项的访问。对象的概念类似面向过程程序设计中的变量
5、概念。举例:对上例中定义的类的应用void main()Rectangle aRectangle;/声明了一个名为aRectangle对象 aRectangle.Assign(2,2);/为该对象的私有成员a,b赋值,即/aRectangle.a=2;aRectangle.b=2coutaRectangle.Square()endl;/调用该对象Square方法,输出该对象/的面积 类是一个抽象概念,而对象是具体的实例。类就如同人的抽象概念,人都具有共同的外部特征和行为特征,就象类的属性和方法,而对一个具体的人,就是一个人的实例,他自然具有人都具有共同的外部特征和行为特征。private和pu
6、blic成员class Rectanglepublic:int a,b;int Square()return a*b;int Girth()return 2*(a+b);修改上述程序:把修改上述程序:把a,b也定义成也定义成public,则可以不需要则可以不需要Assign方法:方法:void main()Rectangle r;r.a=2;/在类外访问在类外访问publicr.b=2;/属性属性a和和b。couta=2;r-b=2;coutSquare();对指针,必须先创建对象,后使用该对象。对指针,必须先创建对象,后使用该对象。对指针指向对象成员的访问类似结构指针,用符号对指针指向对象成
7、员的访问类似结构指针,用符号-。建立一个三角型类(TriAngle):字段:三条边长 方法:计算面积Area 计算周长Girth 计算三个内角InteralAngle 判断三角型类型(是等腰BothSame,是等边AllSame还是直角RightTriAngle三角形 是钝角obtuse三角形还是锐角sharp三角形。面向对象的特征之一:封装面向对象的特征之一:封装“封装”是包含和控制访问一组关联项的能力。类提供一个最通用的方式来封装项。封装使您可以将 类中的数据和过程作为一个单元来使用。您可以同时处理多个对象而不会混淆,因为每个对象都由该类的一个唯一实例来表示。封装还使您可以控制如何使用数据
8、和过程。可以使用访问修饰符(如 Private 或 Protected)来防止外部过程执行类方法或读取与修改属性和字段中的数据。面向对象的特征之一:封装面向对象的特征之一:封装 应当将类的内部详细信息声明为 Private 以防止在类外使用它们,此技术称为“数据隐藏”。隐藏类的实现详细信息可以防止这些信息被以不希望的方式使用。例:关于封装 上例中可以在Rectangle中定义public int a,b;则在Main中可以用R.a和R.b访,无法通过类内部机制对a,b的合法性控制。定义private int a,b;可以防止外部程序修改字段a,b,而通过Assign对字段a,b赋值可以对字段值
9、地合法性进行检查。上述思路对类方法同样适用。构造函数 为类中特殊的成员函数,在声明该类对象或新建该类对象时被调用。构造函数与类同名,并且没有返回类型,包括void。构造函数可以包含参数。例:使用构造函数重写Rectangle类#include class Rectangleprivate:int a,b;public:Rectangle(int x,int y)a=x;b=y;int Square()return a*b;int Girth()return 2*(a+b);void main()/Rectangle r(2,2);/使用对象使用对象Rectangle*r;/使用指针使用指针r=
10、new Rectangle(2,2);/coutr.Square();coutSquare();在定义对象或新建对象时,通过在定义对象或新建对象时,通过构造函数把参数值传递给属性。构造函数把参数值传递给属性。定义构造函数参数可以指定缺省定义构造函数参数可以指定缺省值。值。Rectangle(int x=3,int y=7),则则定义对象时可以不使用参数,参定义对象时可以不使用参数,参数值取缺省值。数值取缺省值。析构函数 析构函数为类中特殊的成员函数,其函数名规定为类名请加。析构函数在对象消亡时被自动调用。析构函数没有返回类型,也不能有参数。析构函数一般包含对在对象生存期内申请的资源进行释放的程
11、序。面向对象的特征之二:继承面向对象的特征之二:继承 类使你可以定义封装一组相关项的数据类型。然而与结构不同的是,类可以继承和扩展其他类的特性。作为新类的基础的类称为“基类”。从基类派生的类称为“派生类”。派生类继承基类中定义的属性、方法和事件。这就意味着可以开发和调试类一次,然后将其作为其他类的基础重复使用。例:建立一个正方型形的类,实现面积和周长及其内接圆面积的计算。#include class Rectanglepublic:int a,b;Rectangle(int x=3,int y=4)a=x;b=y;public:int Area()return a*b;int Girth()r
12、eturn 2*(a+b);class Square:public Rectangle/公有继承公有继承Rectangle public:Square(int x):Rectangle(x,x)/调用父类构造函数调用父类构造函数 double InCircleArea()return 3.14*(a/2)*(a/2);void main()Square r(2);cout正方形面积:正方形面积:r.Area();cout内接圆面积:内接圆面积:r.InCircleArea();调用了基类(父类)的调用了基类(父类)的Area()成员函数。成员函数。补充:Protected成员 Protecte
13、d成员,只能被类内部和其派生类访问。继承的种类 public派生:继承而来的成员访问权限不变。protected派生:继承而来的成员访问权限public和protected都变成protected。private派生:继承而来的成员访问权限都变成private。例:建立三角形,等腰三角型到等腰直角三角形的类继承关系 等腰三角形继承三角型类 只需要已知两条边长。判断是否为直角等腰三角形(方法的重写)计算面积(方法的重写)直角等腰三角形继承等腰三角形类 只需要已知一条直角边长。计算面积(方法的重写)面向对象的特征之三:多态 静态多态-函数重载:基于不同的参数列表,同一个函数名字可以指向不同的函数定
14、义。函数重载中具体调用什么函数在编译时就已经确定。动态多态-允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。动态多态实现是在执行过程中 函数重载#include int max(int x,int y)couty?x:y;float max(float x,float y)couty?x:y;void main()int a,b;float c,d;cinab;coutmax(a,b)cd;coutmax(c,d)endl;1 2integer:21 2Float:2如程序中要写两个函数,分别计算圆面积和正方形面积
15、,函数名可取同名Area。动态多态#include#define PI 3.14class Shape public:/下面定义一个虚拟函数下面定义一个虚拟函数virtual float Area()return 0;class Square:public Shapeint a;public:Square(int x)a=x;float Area()return(float)a*a;class Circle:public Shapepublic:int r;Circle(int x)r=x;float Area()return(float)PI*r*r;bool IsLarger(Shape&
16、a,Shape&b)/不论不论a,b是什么形状是什么形状if(a.Area()b.Area()return true;elsereturn false;void main()Circle c(2);Square s(2);if(IsLarger(c,s)cout圆面积大于正方形面积。圆面积大于正方形面积。;elsecoutb.Area()时,实际调用的不是时,实际调用的不是shape中的中的Area,而是而是Square和和Circle中的中的Area。尝试把尝试把virtual去除,则调用的都将是去除,则调用的都将是Shape中的中的Area,始终输出始终输出“正方形面积大于圆面积。正方形面
17、积大于圆面积。”。上例使用了对象引用,也可以使用对象指针实现多态,上例使用了对象引用,也可以使用对象指针实现多态,但不能使用对象变量。但不能使用对象变量。使用对象指针bool IsLarger(Shape*a,Shape*b)if(a-Area()b-Area()return true;elsereturn false;void main()Circle c(2);/Circle c=new Circle(2);Square s(2);/Square s=new Square(2);if(IsLarger(&c,&s)/IsLarge(c,s)cout圆面积大于正方形面积。圆面积大于正方形面积。;elsecoutb.Area()return true;elsereturn false;void main()Circle c(2);Square s(2);if(IsLarger(c,s)cout圆面积大于正方形面积。圆面积大于正方形面积。;elsecout正方形面积大于圆面积。正方形面积大于圆面积。;将始终输出将始终输出“正方形面积大于圆面积。正方形面积大于圆面积。”,因为始终调用了因为始终调用了shape中的中的Area。