为什么用面向对象编程?(chatgpt 回答)
面向对象编程(OOP)是一种程序设计范式,它将数据和行为封装在对象中,并通过对象之间的交互来实现程序的逻辑。使用面向对象编程有以下几个优点:
-
模块化和重用性:面向对象编程可以将代码组织成多个对象,每个对象负责不同的功能。这种模块化的设计使得代码更易于管理和维护,并且可以通过重用对象来减少重复代码。
-
抽象和封装:面向对象编程允许我们将现实世界中的事物抽象成对象,通过封装数据和行为在对象中,隐藏了对象的内部实现细节,只暴露必要的接口,提高了代码的安全性和可靠性。
-
继承和多态:继承允许我们基于已有的类创建新类,从而实现代码的重用和扩展。多态性使得不同的对象可以对同一个消息作出不同的响应,提高了代码的灵活性和可扩展性。
-
更易于理解和维护:面向对象编程提供了一种自然的思维方式,将现实世界的概念映射到代码中,使得代码更易于理解、调试和维护。
总的来说,面向对象编程是一种强大的编程范式,能够提高代码的质量、可重用性和可维护性,使得程序设计更加灵活和高效。
类和对象
类:是对象共同特征的描述; 对象:是真实客观存在的东西
C++中如何设计类
class 类名{
1、成员变量(代表属性,一般是名词)
2、成员函数(代表属性,一般是动词)
};
例子
class Phone{
public:
//属性(成员变量)
string brand;
double price;
//行为(函数)
void call(){
打电话的功能
}
void playGame(){
玩游戏的功能
}
};
类名建议
类名首字母建议大写、英文、有意义
满足驼峰模式,不能用关键字,满足标识符规定;
如何得到类的对象 如何使用对象属性
类名 对象名; 访问属性: 对象名.成员变量
Phone phone; 访问行为:对象名.函数名(...)
面向对象的三大特征
封装
原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
需求:定义一个类描述人
属性:姓名,年龄(名词)
行为:吃饭,睡觉(动词)
实例:
#include<iostream>
#include<string>
using namespace std;
class Phone {
public:
//属性(成员变量)
string brand;//品牌
double price;//价格
//行为(成员函数)
void call() {
cout << "打电话的功能" << endl;
}
void playGame() {
cout << "玩游戏的功能" << endl;
}
};
int main() {
//创建一个手机对象
Phone phone;
//赋值
phone.brand = "华为nove11 se";
phone.price = 1999.0;
//取值
cout << "品牌:" << phone.brand << endl;
cout << "价格:" << phone.price << endl;
//访问函数
phone.call();
phone.playGame();
return 0;
}
private关键字
私有目的:信息隐藏,以便加以访问控制,比如:让正确的数据赋值成功,让错误的数据赋值失败
private是一个权限修饰符;可以修饰成员(成员变量和成员函数);
被private修饰,表示私有,只能在本类中才能使用,不能被类外代码直接访问;
针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
提供“set_变量名(参数)"函数,用于给成员变量赋值,函数用public修饰
提供"get_变量名()"函数,用于获取成员变量的值,函数用public修饰
被public修饰,表示共有,在所有地方都能使用;
被protected修饰的,表示受保护,在本类及派生类中访问,不能被其他类代码直接访问;
this
作用: 1. 指向当前对象
2.区别成员变量和局部变量
class GirlFriend{
private:
int age=20;//成员变量
public:
void method(){
int age=10;//局部变量
cout<<this->age<<endl;
}
};
int main(){
GirlFriend gf;
gf.method();
return 0;
}
结果:输出20
构造函数
作用:
创造对象时,由系统调用,对对象进行初始化。
分类:
无参构造函数:初始化对象时,成员变量的数据均采用默认值。
有参构造函数:初始化对象时,可以为对象属性进行赋值。
构造函数格式
特点:1.函数名与类名相同,且大小写也要一致
2.没有返回值类型,连void也没有
3.没有具体的返回值(不能由return返回结果数据)
4.如果没有写构造函数,系统会默认提供构造函数
class 类名{
public:
类名(){};//默认构造函数
类名(参数列表){};//带参数的构造函数
};
实例:
#include<iostream>
#include<string>
using namespace std;
class Student {
private:
string name;
int age;
public:
//无参构造函数
Student() {
name = "";
age = 0;
}
//有参构造函数
Student(string name, int age) {
this->name = name;
this->age = age;
}
//设置姓名
void setName(string name) {
this->name = name;
}
//获取姓名
string getName() {
return name;
}
//设置年龄
void setAge(int age) {
this->age = age;
}
int getAge() {
return age;
}
};
int main() {
//创建对象
//无参构造
Student student1;
//赋值前取值
cout << "姓名:" << student1.sgetName() << endl;
cout << "年龄:" << student1.getAge() << endl;
//赋值
student1.setName("张三");
student1.setAge(18);
//取值
cout << "姓名:" << student1.getName() << endl;
cout << "年龄:" << student1.getAge() << endl;
//有参构造
Student student2("李四",19);
//取值
cout << "姓名:" << student2.getName() << endl;
cout << "年龄:" << student2.getAge() << endl;
return 0;
}
输出:
构造函数注意事项
1.构造函数的定义
如果没有定义构造函数,系统将给出一个默认的无参数构造函数
如果定义了构造函数,系统将不再提供默认的构造函数
2.构造函数的重载
带参构造函数和无参构造函数,两者函数名相同,但参数不同,这叫做构造函数的重载。
推荐:无论是否使用,都手动书写无参数构造函数和带全部参数的构造函数。
析构函数
作用
用于在对象被销毁时,进行清理操作;
格式
与类名相同,前面加速波浪号(~),没有返回类型,并且不带参数。
class Student(){
public:
~Student(){
cout<<"析构函数,删除对象"<<endl;
}
};
封装总结
1.类名要见名知意
2.成员变量使用private修饰
3.构造函数:无参构造函数 有参构造函数即带有全部参数的构造函数
4.成员函数
提供每一个成员变量对应的set_Xxx()/get_Xxx()。
如果还有其他行为也需要写上