面向过程编程pop
概念
是以功能为中心,专注于问题解决,将整个需求分解为若干个步骤,每个步骤定义为一个函数,通过逐步调用函数来实现整个功能,完成需求。
它以函数为最小单位,强调的是功能和行为,主要考虑怎么做的问题,即算法。
举例:需求是张三早上开宝马去公司上班。梳理为如下步骤(只要实现就可以):
1.起床洗漱
2.进入车库,打开车门,坐入车内,系好安全带
3.踩刹车,打火启动车辆
4.挂前进档,驾驶车辆驶向目的地
5.到公司停车熄火解安全带下车关门锁车
优缺点
优点:符合人思考的思维方式,各个代码块分工很明确,需要实现的功能拆分的清晰明了。
缺点:数据和函数分开的,当数据结构发生改变时,所有和该数据有关的函数都要需修改。程序的维护性很差,不易于复用(程序在很多地方可以使用)和扩展(如果数据或功能发生改变,便于完成)
面向对象编程oop
概念
考虑的核心不是如何实现需求,而是将整个需求里面涉及到的事物找出来,将事物的特征用数据描述,并且抽象为属性(事物的特征,和其他事物的区别),将事物的行为(事物能干什么)抽象为方法(函数),最后,将这些事物的属性(特征)和方法(对行为的实现)封装到一起形成类,面向对象编程就是通过这些类的相互协作来完成整个需求。
它以类为最小单位。强调的是如何设计类,如何通过类之间的协作,完成需求的实现。
公式
面向对象编程=类+对象+封装+继承+多态+消息(对象调用属性或方法),其中封装+继承+多态 是面向对象程序设计的三大特性。
举例:需求是张三早上开宝马去公司上班。
面向对象编程进行分解:
1.找出整个需求中涉及到的事物:
人类(张三)
车(宝马车)
公司(特指司)
2.再将事物的特征用数据描述并且抽象为属性:
人类:姓名、性别、身份证号、工号、岗位
车:车牌,车品牌,车型、手动或自动
公司:公司名、营业执照编号、公司地址、经营范围、公司性质
3.将行为抽象为方法(函数):
人类:会开车、会工作
车:启动、行驶、加速减速、刹车、停车驻车
公司:营业(提供产品或服务)、提供就业岗位
4.将属性和方法(函数)封装成类,然后使用这些类,将类实例化出来具体的对象,最后通过对象来调用类中的属性和方法(函数),实现整个需求。
类的概念
类是描述了一组具有相同的特征(属性)和相同的行为(方法)的对象,类是对象的模板,而对象是类的具体实例化。
对象
对象是现实世界中存在的事物,是类的一个具体实例,比如张三是人类的实例、宝马325是汽车的实例。
属性
属性就是类中的特征数据,也叫做类的数据成员。
方法
方法就是类中的函数,用来实现一个行为功能,也叫做类的成员函数
类与对象
类的定义
语法格式:
类的说明部分
一般放在头文件中.h结尾,用来声明的,不是用来实现的,头文件存放函数声明、类、静态变量等
class 类名//class是定义类的关键字,后面要跟上类名(标识符,按照规范应该使用大驼峰命名法,首字母大写,其他字母小写)
{//大括号表示类的作用域,称为类体private:私有的数据成员和私有的成员函数protected:保护的数据成员和成员函数public:公有的数据成员和成员函数//private、protected、public关键字,称为访问控制修饰符,描述类中成员的可见性
};//分号表示类定义结束
类的实现
可以在另一个源文件中,实现类中的成员函数
类中的成员函数可以在类内直接写出函数定义,这就是在类内实现,也可以只在类中声明函数的原型,但不写方法体,然后去类外实现函数的定义。
类需要写在main函数的外面。
//定义一个矩形类,类名是Rect
class Rect
{//属性:长和宽,命名规范:m表示类中成员,m_数据类型缩写+属性名(建议使用大驼峰命名法),一般是私有的,属于隐私。
private:int m_nLength;int m_nWidth;//方法(类中的成员函数),命名规范:以一个或多个单词来组成,第一个单词全小写,其余单词首字母大写。
public:void setLength(int nLen);//设置矩形的长度void setWidt(int nWidth);//设置矩形的宽度int getArea()//计算矩形的面积,计算一个值,返回,无需参数int getperimeter()//计算矩形的周长
};
//在源文件中实现头文件中类的方法体,需要在方法名前面加上类名和域运算符,如:Rect::
void Rect::setLength(int nLength)//设置长和宽
{m_nLength = nLength;
}
void Rect::setWidth(int nWidth)
{m_nWidth = nWidth;
}
int Rect::getArea()//计算面积和周长
{return m_nLength * m_nWidth;
}
int Rect::getperimeter()
{return (m_nLength+ m_nWidth)*2;
}
int main()
{//在这里使用类和对象完成程序的逻辑Rect r1, r2;//实例化出对象//通过对象名加点,来调用类中的函数r1.setLength(6);r1.setWidth(4);r2.setLength(10);r2.setWidth(5);cout << "r1的面积" << r1.getArea() << endl;cout<<"r1的周长"<<r1.getperimeter()<<endl;cout << "r2的面积" << r2.getArea() << endl;cout << "r2的周长" << r2.getperimeter() << endl;return 0;
}
2.2成员的访问控制
在类体中,有属性(数据成员)和方法(成员函数),他们在程序中的使用受到成员的访问权限的限制,如果没有声明访问控制权限,默认为私有权限访问权限分为三种:
private
私有的访问权限,在private关键字后声明的属性和方法具体私有访问权限,即只允许本类成员函数访问,在类外是无法访问的,属性一般设置为私有,目的是为保护对象的隐私。
protected
保护访问权限,在protected后面声明的属性和方法具有保护访问权限,保护成员是有限访问的,即能被本类的成员函数访问,也能被派生类访问(继承的知识点,可以理解为本类的儿孙也可以访问),类外无法访问
public
公有访问权限,在public关键字后面的属性和方法具有公有访问权限,公有的成员对类内和派生类(子孙类)以及类外都可以访问(不做任何保护),一般会把方法设置为公有,因为方法需要对外提供调用服务。
2.3类的数据成员和成员函数
类中的数据成员(属性),描述的是对象的特征,必须在类体中定义,他们的定义方式与一般的变量定义相同,但是受到访问控制修饰符的限制。
定义数据成员注意事项
1.数据成员初始化与变量初始化形式有所不同,不能使用小括号初始化,可以使用=或{}初始化。
2.数据成员的类型可以是任意类型,如果是数组类型,必须指定数组的大小。
3.多个数据成员之间是不能重名的,一个类作为一个作用域,不能重名。
4.类定义在前,使用在后。如果在类A中使用了类B(B是A类的属性),如果B还未定义,需要做一个前向声明:class B;
class B;
class A
{B m_Bobj;
};c
类中的成员函数(方法)
描述的是对象的行为,即该类对象能执行什么操作,目的是能完成什么功能,向类外提供一种服务。
定义成员函数的注意事项
1.类外定义成员函数时,需要在函数名前使用类名+域运算符来指定是哪个类的成员函数。
2.一个类中的多个成员函数可以重载,即函数名相同,但形参个数或类型不同。函数返回值是不能构成重载的。
3.类的成员函数也可以是内联函数,有两种方法可以定义内联函数,一种是将成员函数的定义直接写在类体中;另一种是在类外定义成员函数的时候,使用inline来声明。
4.类的成员函数的形参也可以有默认值。
2.4对象的创建和访问
对象的创建
如何使用一个类:先创建类的对象,然后操作对象完成具体的功能。在创建对象的时候,需要说明该对象所属的类,创建对象就是这个类的一次实例化过程。
举例:在栈内存空间创建对象:Rect r1;
在堆内存空间创建对象(动态创建):Rect *pr2=new Rect;
对象的访问(使用对象)
操作一个对象是通过访问对象的成员(属性和方法)来实现的。
如果是普通对象,可以使用.
运算符去访问如r1.getArea
,如果是对象指针,pr2->getArea()
类和对象的关系
类与对象是抽象和具体的关系,类是创建对象的模板,基于这个模板可以创建很多个对象,每个对象的属性值可以不同,但是共用了类中的方法。
在程序运行时类是静态的,无法改变的,而对象是动态的,对象的属性是可以被改变的。一个对象就是某个类的实例,创建对象的过程称为类的实例化。
对象被创建后才真正存在,对象具有一定的生命周期,我们可以通过对象名、指针、引用来区分对象。
一个类实例化出来的多个对象,他们分别拥有自己的属性,且相互独立,每个对象都要分配内存空间,而成员函数是有所有对象共享的。
对象占用内存空间的大小
cout<<"Rect类的大小:"<<sizeof(Rect)<<endl;类的大小
cout<<"Rect类的大小:"<<sizeof(r1)<<endl;r1对象的大小
cout<<"Rect类的大小:"<<sizeof(r2)<<endl;r2对象的大小
cout<<"Rect类的大小:"<<&r1<<endl;r2对象的地址
cout<<"Rect类的大小:"<<&r2<<endl;r2对象的地址