4.1 面向对象程序设计的基本特点
4.1.1 抽象
抽象是指对具体问题(对象)进行概括,抽出一类对象的公共性质并加以描述的过程。
在面向对象的软件开发中,首先注意的是问题的本质及描述,其次是解决问题的具体过程。一般来讲,对一个问题的抽象应包含两个方面:数据抽象和行为抽象。前者描述某类对象的属性或状态,后者描述的是某类对象的共同行为或功能特征。
举例:对人进行抽象
共同的属性如姓名年龄性别等。用C++语言变量来表达:string name,string sexm,int age
共同的行为如吃饭行走工作学习等行为,这构成了人的行为抽象部分,可以用C++语言的函数表达:eat(),walk().work(),study()
4.1.2 封装
封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的函数代码进行有机的结合,形成类,其中的数据和函数都是类的成员。
例如:时钟类
class Clock{ //类名
public: //外部接口
void setTime(int newH=0,int newM=0,int newS=0); //行为,代码成员
void showTime(); //行为,代码成员
private: //特定访问权限
int hour,minute,second; //属性,数据成员
};
4.1.3 继承
允许程序员在原有类特性的基础上,进行更具体,更详细的说明。
4.1.4 多态
一段程序能够处理多种类型对象的能力。在C++语言中,这种多态性可以通过强制多态、重载多态、类型参数化多态、包含多态4种形式来实现。
4.2 类和对象
类是面向对象程序设计方法的核心,利用类可以实现对数据的封装和隐蔽。
在面向对象程序设计中,程序模块是由类构成的。类是对逻辑上相关的函数与数据的封装,它是对问题的抽象描述。
4.2.1类的定义
以时钟类为例
class Clock{
public:
void setTime(int newH=0,int newM=0,int newS=0);
void showTime();
private:
int hour,minute,second;
};
分别封装了时钟的数据和行为,分别称为Clock类的数据成员和函数成员。
定义类的语法形式如下:
class 类名称
{
public:
外部接口
protected:
保护型成员
private:
私有成员
};
4.2.2 类成员的访问控制
有以下3种:公有类型public,私有类型private和保护类型protected
公有类型定义了类的外部接口。用public关键字声明,在类外只能访问类的公有成员。对于时钟类,从外部只能调用setTime()和showTime()这两个函数成员来改变或查看时间。
私有成员只能被本类的成员函数访问,来自类外部的任何访问都是非法的。
保护类型成员的性质与私有成员性质相似,其差别在于继承过程中对产生的新类影响不同。
4.2.3 对象
类的对象就是该类的某一特定实体(实例)。比如:将整个公司的雇员看做一个类,那么每一个雇员就是该类的某一特定实体,也就是一个对象。
声明一个对象:
类名 对象名;
Clock myClock; //声明一个时钟类型的对象myClock
注意:对象所占内存空间只是用于存放数据成员,函数成员不在每一个对象中存储副本,每个函数的代码在内存中只占据一份空间。
定义了类及其对象就可以访问对象的成员。这里访问采用的是”.“操作符,访问数据成员的一般形式: 对象名.数据成员名
调用函数成员的一般形式是 对象名.函数成员名(参数表)
比如:访问类Clock 的对象myClock的函数成员ShowTIme()的方式如下:myClock.showTime()
4.2.4 类的成员函数
成员函数的实现
函数的原型声明要写在类体中,原型说明了函数的参数表和返回值类型。而函数的具体实现是写在类定义之外的。与普通函数不同的是,实现成员函数时要指明类的名称。
程序实例:
#include<iostream>
using namespace std;
class Clock{
public:
void setTime(int newH=0,int newM=0,int newS=0);
void showTime();
private:
int hour,minute,second;
};
//时钟类成员函数的具体实现
void Clock::setTime(int newH,int newM,int newS){
hour = newH;
minute = newM;
second = newS;
}
inline void Clock::showTime(){
cout<<hour<<":"<<minute<<":"<<second<<endl;
}
int main(){
Clock myClock;//定义对象myclock
cout<<"First time set and output:"<<endl;
myClock.setTime(); //设置时间为默认值
myClock.showTime(); //显示时间
cout<<"second time set and output:"<<endl;
myClock.setTime(8,30,30); //设置时间为8:30:30
myClock.showTime(); //显示时间
return 0;
}
4.3 构造函数和析构函数
在定义对象的时候进行的数据成员设置称为对象的初始化。 由构造函数完成。
在特定对象使用结束时,还经常需要进行一些清理工作。由析构函数完成。
对象建立的过程: 在程序执行过程中,当遇到对象声明语句时,程序会向操作系统申请一定的内存空间用于存放新建的对象。
构造函数的作用就是在对象被创建时利用特定值构造对象,将对象初始化为一个特定的状态。构造函数也是类的一个成员函数,除了具有一般成员函数的特征之外,还有一些特殊的性质:构造函数的函数名与类名相同,而且没有返回值;构造函数通常被声明为公有函数。只要类中有了构造函数,编译器就会在建立新对象的地方自动插入对构造函数调用的代码。因此,通常说构造函数在对象创建的时候被自动调用。
class Clock{
public:
Clock(nt newH,int newM,int newS); //构造函数
void setTime(int newH=0,int newM=0,int newS=0);
void showTime();
private:
int hour,minute,second;
};
//构造函数具体实现
void Clock::Clock(int newH,int newM,int newS){
hour = newH;
minute = newM;
second = newS;
}
析构函数用来完成对象被删除前的一些清理工作。在对象的生存期即将结束的时候被自动调用的。它的调用完成之后,对象也就消失了,相应的内存空间也被释放。
和构造函数不同的是析构函数不接受任何参数,但可以是虚函数。