为什么要从面向过程转到面向对象?
随着计算机发展,问题场景越来越复杂,我们很难再描述每一个可能的过程
转而描述每一个实体(属性+行为),这就是面向对象的核心思想
1、抽象
识别出各个实体及其属性和行为,类就是对某一事物的抽象
下面以游戏为例来说明
属性:ID,段位,英雄,战力,场次...
行为:移动,放技能,普攻,回城,吃血包...
属性:名称,伤害,效果,价格,数量...
行为:购买,出售,合成...
OK,至此我们清楚了什么是抽象,以及区分类的属性和行为。
2、UML类图
用来规范描述一个事物的属性和行为
以上面的 “泣血之刃” 为例
数据成员属性后需要加上数据类型
属性、行为前的 + 和 -
+表示为public //公有成员
-表示为private //私有成员
3、类定义
定义一个类的成员变量和成员函数(语句同样以 ; 结尾)
类通过实例化成为真实存在的对象(存在于内存中)
我们使用关键字class来进行类定义
4、类成员函数
(1)构造函数(constructor)
对象实例化时,在分配的空间上构造对象,目的就是初始化对象
① 创建对象时自动调用
② 有默认的构造函数,并不是必须定义
③ 默认构造函数是无参的,也可以定义有参的
④ 可以有多个重载
⑤ 不可以有返回值
(2)析构函数(destructor)
对象生命期结束时,回收空间前,完成对象清理工作
① 一定无参数
② 不可以有返回值
③ 函数前有~(算是一个标志)
此外,构造函数和析构函数的函数名都必须和类名相同
5、对象实现
#include <iostream> using namespace std; class Circle { public: float radius; //这里的radius是类的数据成员 Circle(float radius) //有参构造,括号里的radius为形式参数 { this->radius = radius; //this指针在类定义内部使用,指向当前对象 } float getS() { return 3.14 * radius* radius; } }; int main() { Circle Circle1(1.2); //实例化对象,一个圆的半径为1.2 cout << Circle1.getS(); //访问对象成员,调用求面积的函数并输出结果 }
6、封装
将类的一些成员变量或方法藏起来,不允许外界直接操作(控制类成员在外部的可见性)
访问控制属性:
public:外部可通过 对象.名字 访问
protected
private:外部不可直接通过 对象.名字 访问
7、getter、setter方法
为某些私有成员提供外部读写方法,一般都是public
getter函数格式:
类型 get_XXX() const{
return XXX;
}
(通常设置为const函数,无参且有返回值)
setter函数格式:
void set_XXX(){
this->XXX=XXX;
}
(通常接受const参数,有参且无返回值)
来看例子,代码有点长,各位好好理解
#include <iostream> using namespace std; class Book { private: string name; int count; public: Book(string name) { count = 0; this->name = name; } int get_count() const { return count; } string get_name() const { return name; } void set_count(int count) { if (count < 0) { count = 0; } this->count = count; } void set_name(const string& name) { this->name = name; } void add_count() { count++; } }; int main() { Book book1("高等数学"); cout << book1.get_name() << "库存: " << book1.get_count() << endl; book1.add_count(); cout << book1.get_name() << "库存: " << book1.get_count() << endl; }
8、this指针
在类成员函数定义内部使用,指向当前对象
利用this指针编写Student的有参构造函数,避免变量名覆盖问题:
Student(int id,string name,int age,float score){ this->id = id; //由于形参名把数据成员名覆盖掉了,所以用this指针表明当前对象的数据成员 this->name = name; this->age = age; this->score = score; }
也可使用其他方式避免同名覆盖,如下
Student(int _id, string _name, int_age, float _score){ id = _id; name =_name; age = _age; score = score; }
这样就可以不用this指针
OK,今天内容到此为止,你学废了吗?