在我们 C++ 语言的第一讲里,我们谈到了 C++ 对于 C 而言,是在 C 的基础上多了一些语言的新特性,那么到底多了些什么呢?
今天我们要讲的内容就是 C++ 多出来的最为突出的特性 — 面向对象的程序设计 OOP。
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。
它可能包含数据、属性、代码与方法。对象则指的是类的实例。
它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。
Wikipedia
这段话看起来可能有些费解,面向对象编程是一种编程的方式,它是一种以 对象 object 为基本单位去看待问题和解决问题的方法。
而要有对象,先要有 类 class,类是创建对象的模版,现在,就让我们从类开始,揭开面向对象程序设计的面纱。
类 class,在诸多面向对象的程序设计语言中,类都有着类型、类别、分类的含义。
类是一个抽象的概念,看不见摸不着却真实存在,类高度概括了世界上某一部分事物的共性:
我们用例子来说明这个问题,拿最常见的「人类」为例,我们讨论的不是你、我、他,而是整个人类的共性,经过思考,我们发现,人类有着这样一些共有的属性:
还有很多,除此之外,人类还有着这样一些共有的行为:
等等,也有很多。
经过这样的分析,我们就可以用 C++ 语言定义一个「人类」,注意,这只是个抽象的概念。
我们看代码示例,这是一个简化版的人类:
#include <iostream>
using namespace std;
class Human {
// 类的属性
string name;
// 类的行为
void study() {
cout << name + " is studying..." << endl;
}
};
这样,我们就完成了 C++ 中第一个类的定义。
我们看到,这个类定义了人类都有一个共有的属性:姓名;都有一个共有的行为:学习。
具体到了语言中,我们发现,属性就是变量,行为就是函数。
然而这个类还不够完善,我们再加上几个属性和行为,一个稍微完善的人类是这样的:
#include <iostream>
using namespace std;
class Human {
// 私有的属性
private:
string name;
string gender;
int age;
// 公有的行为
public:
void study() {
cout << name + " is studying..." << endl;
}
void work() {
cout << name + " is working..." << endl;
}
void play() {
cout << name + " is playing..." << endl;
}
// Set 方法和 Get 方法
const string &getName() const {
return name;
}
void setName(const string &name) {
Human::name = name;
}
const string &getGender() const {
return gender;
}
void setGender(const string &gender) {
Human::gender = gender;
}
int getAge() const {
return age;
}
void setAge(int age) {
Human::age = age;
}
};
哪里发生了变化呢?
首先,我们增加了两个属性,gender 和 age。
其次,增加了一些行为,work 和 play,还有几个函数是 set
或 get
开头的,我们称为 set 方法和 get 方法。
除了这两处变化之外,我们发现,在属性的上方出现了一个 private
,而在行为函数的上方出现了 public
,这个做法叫做 封装 encapsulation
,目的是隐藏类的数据,而开放类的对外的接口,就是函数。
通过这样的过程,我们就定义了一个比较完善的类。
问题来了,类我们定义好了,它有什么用?
别忘了,我们学习的面向对象的程序设计,在这里,对象 object 才是程序设计的基本单元,但是,对象在哪呢?
对象是类的实例,类是创建对象的模版
对象就是由类来生成的。
当我们定义好了类之后,就可以使用类来创建对象,方式非常简单:
类名 对象名;
这样,一个当前类的对象就创建出来了,而这个对象就拥有了这个类所有的属性和行为。
在今天的最后,我们创建一个人类的对象,并使用这个对象调用一下这个类的属性和行为:
#include <iostream>
using namespace std;
class Human {
// 私有的属性
private:
string name;
string gender;
int age;
// 公有的行为
public:
void study() {
cout << name + " is studying..." << endl;
}
void work() {
cout << name + " is working..." << endl;
}
void play() {
cout << name + " is playing..." << endl;
}
// Set 方法和 Get 方法
const string &getName() const {
return name;
}
void setName(const string &name) {
Human::name = name;
}
const string &getGender() const {
return gender;
}
void setGender(const string &gender) {
Human::gender = gender;
}
int getAge() const {
return age;
}
void setAge(int age) {
Human::age = age;
}
};
int main() {
// 创建类的对象
Human tom;
tom.setName("Tom");
tom.setGender("Male");
tom.setAge(18);
cout << tom.getName() << endl;
cout << tom.getGender() << endl;
cout << tom.getAge() << endl;
tom.study();
tom.work();
tom.play();
return 0;
}
/*
output:
Tom
Male
18
Tom is studying...
Tom is working...
Tom is playing...
*/
程序的最后,输出了这个人类对象的姓名、性别和年龄,并调用了三个行为函数:学习、工作和游戏。
而这个人类的实例对象,就是一个活生生的人,他是具体的,而不是抽象的。
所以由类创建对象的过程,就是一个从抽象到具体的过程。