当前位置: 首页 > news >正文

面向对象编程简介

面向对象编程简介

1. 面向过程

在这里插入图片描述

就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调 用就可以了。C语言就是典型的面向过程。

就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调
用就可以了。C语言就是典型的面向过程。
面向过程程序设计是一种解决思路 :

  • 提出问题

  • 分析问题的处理流程

  • 将大问题分解为小问题

  • 如果小问题比较复杂,就继续划分小问题为更小的问题

  • 然后通过小模块一一解决小问题在这里插入图片描述

  • 最后再根据整个业务流程将这些小问题串在一起(调用函数)

把大象装进冰箱需要几步?

  • 打开冰箱门
  • 把大象关进冰箱
  • 关上冰箱门

这就是典型的面向过程的思路。为了实现这个过程我们需要写三个函数,打开冰箱函数、把大象关进冰 箱函数、关上冰箱函数。三个函数依次执行就实现了最终的效果。

  • 打开冰箱函数
//打开冰箱门
返回值 openRefrigerator(参数表){//一些打开冰箱们前的操作//例如,定义变量,申请内存空间/*//计算过程//做一些其他操作//处理异常等*/std::Cout << "冰箱门打开了" << std::Endl;//做一些善后工作,例如释放空间等return 返回值;}
  • 把大象关进冰箱函数
/把大象关进冰箱函数
返回值 put(参数表){//一些把大象关进冰箱的操作//例如,定义变量,申请内存空间/*//计算过程//做一些其他操作//处理异常等*/std::Cout << "大象关进冰箱了" << std::Endl;//做一些善后工作,例如释放空间等return 返回值;}
  • 关上冰箱函数
 //关上冰箱函数
返回值 closeRefrigerator(参数表){//一些关上冰箱的操作//例如,定义变量,申请内存空间/*//计算过程//做一些其他操作//处理异常等*/std::Cout << "冰箱关闭了" << std::Endl;//做一些善后工作,例如释放空间等return 返回值;}

调用

 int main(){openRefrigerator();put();closeRefrigerator();return 0;

面向过程强调的是功能行为,以函数为最小单位,考虑怎么做。面向过程是一种以函数为基本单位的编 程方法,它将一个复杂的问题分解为多个步骤,每个步骤对应一个函数。

2 面向对象

面向对象会把事物抽象成对象的概念,先抽象出对象,然后给对象赋一些属性和方法,然后让每个对象
去执行自己的方法。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-对于把大象装进冰箱这个例子来说。
面向对象的分析过程:

  1. 分析动作是由那些实体(对象)发出的; //人 ,冰箱,大象

  2. 定义主体(对象),为其增加属性和功能;

    • //人,人需要有打开关闭冰箱,及将大象放入冰箱的功能(行为);

    • //冰箱,冰箱需要具有能开门和关门的属性(属性);

    • //大象,大象需要具有能够进入冰箱的功能(行为)

将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做

  • 大象对象
Elephant{
类型 状态; (opening,closed)
}
  • 冰箱对象
Refrigerator{返回值 enterRefrigerator(){std::cout << "进入冰箱" << std::endl;}}
  • 人对象
Human{返回值 openRefrigerator(){std::cout << "打开冰箱" << std::endl;}返回值 closeRefrigerator(){std::cout << "关闭冰箱" << std::endl;}返回值 put(){std::cout << "把大象关进冰箱" << std::endl;}}
  • 创建对象完成过程
int main(){// 创建大象对象Elephant;// 创建冰箱Refrigerator;// 创建人类Human;// 人打开冰箱门Human.openRefrigerator();//冰箱设置为开门状态Elephant.status = opening;// 人把大象关进冰箱Human.put();//大象进入冰箱Elephant.enterRefrigerator();// 人关闭冰箱门Human.closeRefrigerator();//冰箱设置为开门状态Elephant.status = closed;return 0;}

图示就是这样

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

面向对象以对象为核心,将现实世界的事物抽象为对象,每个对象拥有自己的属性和方法。面向对象编
程强调的是对象的封装、继承和多态等特性,通过这些特性实现代码的重用和扩展。在面向对象编程
中,开发者需要更多地关注对象之间的关系和交互,以及如何通过对象来描述和解决问题。

3 面向过程和面向对象的优缺点

面向过程
优点:
流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清楚,便于节点分
析。
效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。
缺点:
耦合度高,扩展性差,后期维护难度比较大。

面向对象
优点:
结构清晰,程序是模块化和结构化,更加符合人类的思维方式;
易扩展,代码重用率高,可继承,可覆盖,可以设计出低耦合的系统;
易维护,系统低耦合的特点有利于减少程序的后期维护工作量。
缺点:
开销大,可要看到我们上述一个简单的例子需要定义三个对象,而且还要设置不同的属性和行为。另外
还要频繁设置对象属性和调用对象行为,使程序显得臃肿。
性能低,因为创建对象和销毁对象都需要损耗一定的性能。

4 面向对象的三个特征

封装
就是把细节隐藏起来,是的代码模块化,让可信的对象对访问自己的属性和方法,对不可信的进行信息
隐藏。
继承
让某个类型的对象的获得另一个类型的对象的属性和方法。通过继承创建的新类称为「子类」或「派生
类」,被继承的类称为「基类」、「父类」或「超类」。 要实现继承,可以通过 继承和组合 来实现。
继承者就是儿子,被继承着就是父亲。
多态
允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋
值给它的子对象的特性以不同的方式运作。简单说就是一句话:允许将子类类型的指针赋值给父类类型
的指针。

5 类和对象

5.1 什么是对象

万物皆对象。任何事物都可以看做对象。 三大基本特征中,最基础的特征就是封装,要理解封装,要知道两 个基本概念:类和对象。

  • 类和结构体在定义时候只是一个蓝图,也是存储在指令中,实例化后才分配内存

5.2 如何描述对象

类似于结构体变量,通过对象的属性(名词,数量词,形容词…)和行为(动词)来描述对象。

描述学生对象: 
属性:年龄、学号、名字 
行为:吃饭、睡觉、学习
  • 任何对象都属于一个类型
学生属于学生类型,不属于老师类型,更不是水果类型
  • 有物体,东西的意思,现实世界中,一切都是对象(是一个具体存在的实体)
学生a、学生b...
  • 任何对象都有属性和行为
属性:年龄、学号、名字
行为:吃饭、睡觉、学习

5.3 什么是类

类是将多个对象的共性提取出来定义的新的数据类型,是对对象属性和行为的抽象描述。类似于结构体类
型。
一个类型就是一个概念,类型描述了一类事物共用的特征和行为

例如:
学生类型
属性:年龄、学号、名字
行为:吃饭、睡觉、学习
零食类型
属性:产地、生产日期、保质期
行为:被人吃
class 类名
{
访问控制属性://行为:用成员函数表示返回类型 函数名(形参表){}//成员函数//属性:用成员变量表示数据类型 变量名;//成员变量
};

类就是类型,是一个抽象的概念,而对象是一个具体存在的实体,是一个类的实例的真实存在。
类(Class)和对象(Object)是面向对象编程(Object-Oriented Programming,简称OOP)中的
两个核心概念。
**类和对象的关系是抽象和实例化的关系。**类是对对象的抽象描述,而对象则是类的具体实例。

5.4 类的定义

类的一般形式

class 类名
{
访问控制属性://行为:用成员函数表示返回类型 函数名(形参表){}//成员函数//属性:用成员变量表示数据类型 变量名;//成员变量
};

访问控制属性--使用class定义的类默认的访问控制属性是private

public:公有成员,类的内部和外部都可以访问的成员
protected:表示该下面的数据成员、成员函数受保护权限,在类内可以访问,类外只有子类可以访问
private:私有成员,只有在类的内部才可以访问的成员
  • 属性 :这个类的一些属性,如学生类包含:年龄、姓名、性别等,我们称为:成员变量
  • 行为 :这个类的一些行为,如学生类包含:吃饭、睡觉、学习等,我们称为:成员函数
练习:描述学生对象
#include <iostream>
using namespace std;
class Student
{//成员函数 行为
public:void eat(const string food){cout << "我吃" << food << endl;}void sleep(const double hour){cout << "我睡了" << hour << "小时" << endl;}void eat(const string corse){cout << "在学" << corse << endl;}void who(){cout << "我叫" << m_name <<  ",年龄" << m_age << "岁,学号是" << m_no <<endl;}//成员变量  属性
public:string m_name;protected: int m_age;private:int m_no;};

5.5 类的大小

在类中,只有成员变量占用内存空间,而成员函数是不占用内存空间的

类占用的内存空间永远是所有成员中占用内存最大成员的倍数(对齐问题)。

#include <iostream>using namespace std;class student{public:void print(){cout << "hello" << endl;}private:int age; double heigh;int score;};int main(){cout << "sizeof(student) = " << sizeof(student) << endl;//24return 0;}

空类的大小为1 避免占用相同的内存

#include <iostream>using namespace std;class student{};int main(){cout << "sizeof(student) = " << sizeof(student) << endl;return 0;}

5.6 类的实例化

我们把类可以理解为一种类型,对象是类中的一种实例。用类创建对象的过程叫做实例化。与结构体变 量定义相似。

int main(){//创建对象,或实例化对象Student s1;Student s2;return 0;}

成员变量在声明时不会分配内存,而是在对象创建时分配内存

5.7 类内成员访问

与结构体变量访问结构体成员一样通过 . 来访问

protected和private成员在类外无法访问

int main(){//创建对象,或实例化对象Student s;s.eat("晚饭");s.sleep(8);s.learn("C++");s.m_name = "abc";//s.m_age = 18;//error protected成员在类外无法访问//s.m_no = 1;//error private成员在类外无法访问s.who();//随机数return 0;   }

为了能使 who 函数正常使用,且不希望在外部修改成员,对程序进行修改

#include<iostream>using namespace std;class Student{public:void eat(const string food){cout << "我吃" << food << endl;}void sleep(const int hour){cout << "我睡了" << hour << "小时" << endl;}void learn(const string course){cout << "我在学" << course << endl;}void who(void){cout << "我叫" << m_name << ",今年" <<m_age << "岁,学号是" << m_no << endl;}void setAge(int age){m_age = age;}void setNo(int no){m_no = no;}public:string m_name;protected:int m_age;private:int m_no;};int main(){//创建对象,或实例化对象Student s;s.eat("晚饭");s.sleep(8);s.learn("C++");s.m_name = "abc";//s.m_age = 18;//error protected成员在类外无法访问//s.m_no = 1;//error private成员在类外无法访问s.setAge(18);s.setNo(1);s.who();return 0;}

5.8 this指针

定义:类的内部都隐藏一个该类类型的指针参数,名为this,可以帮助我们区分类内成员和其他参数。

#include<iostream>using namespace std;class Student{public:void who(void){cout << "name = " << name << endl;}void setName(string name){this->name = name;}private:string name;};int main(){Student s;s.setName("蔡徐坤");s.who();return 0;}

6.面向对象编程的注意事项

  • 要确定所设计的类,那些属性和行为是对外公开的,哪些是隐藏的。默认情况下(不加访问修饰

    词),class中所有的成员都是private,外界无法直接访问。

  • 要符合高内聚,低耦合的设计思想

    • 高内聚(High Cohesion)是指一个模块或类应该紧密地完成一个特定的功能或一组相关的功

    能。高内聚意味着每个模块或类都有一个清晰定义的职责,并且模块或类内部的各个部分都是

    协同工作的,以实现这个职责。这样可以提高代码的可维护性和可重用性,因为模块或类的功

    能相对集中,更容易理解和修改。

    • 低耦合(Low Coupling)是指模块或类之间的依赖关系应该尽可能地减少。低耦合设计可以

    使模块或类更加独立,减少相互依赖和直接耦合,从而更容易进行模块替换、测试和重用。这

    也有助于降低系统的复杂性,使其更容易理解和维护。

  • 在定义类的时候,所有的class都可以被替换为struct,代码不会出错,但是class表示一个类,而

    struct表示的是一种数据结构, class和struct最大的区别是,默认情况下(不加访问修饰

    词),struct中所有的成员都是public

 #include<iostream>using namespace std;class Student{std::string m_name;void print(){std::cout << "class Student" << std::endl;}};struct Teacher{std::string name;void print(){std::cout << "class Teacher" << std::endl;}};int main(){Student stu;stu.m_name = "abc";//error 默认是私有的,类外不可访问stu.print();//error默认是私有的,类外不可访问Teacher tea;tea.name = "def";tea.print();return 0;}
  • 在写类的时候,一般一个标准的类都分为两个文件(.h/.cpp)
    • 在头文件中声明类型和函数

test_1.h

 #ifndef __TEST_1_H__#define __TEST_1_H__#include<iostream>class Student{public:void setName(const std::string name);void setAge(const int age);void who();private:std::string m_name;int m_age;};#endif
  • 在源文件中实现函数
  • 如果类的成员函数在类中声明,在类外定义,则在定义的时候需要加上作用域运算符

test_1.cpp

 #include"test_1.h"#include<iostream>void Student::setName(const std::string name){m_name = name;}void Student::setAge(const int age){m_age = age;}void Student::who(){std::cout << "m_name = " << m_name << ", m_age = " << m_age << std::endl;}

test.cpp

 #include<iostream>#include"test_1.h"using namespace std;
inline void Student::who(){std::cout << "m_name = " << m_name << ", m_age = " << m_age << std::endl;}int main(){Student s;s.setName("abc");s.setAge(18);s.who();return 0;}
  • 只读成员函数(常函数)
    • 在C++成员函数的形式参数列表的后面,可以加上一个const来修饰
返回值类型 函数名(参数表) const{函数体;
}

表示这个成员函数,是只读成员函数,只能读取成员变量的值,保证不修改成员变量的值 (增强程序的健壮性,防止程序员在函数中对成员变量的值进行误修改)

不允许修改成员变量

#include<iostream>class Student{void setName(std::string name) const{//m_name = name;std::cout << "m_name = " << std::endl;}private:std::string  m_name;};int main(){return 0;}
  • 如果在指定成员函数中,修改了成员变量的值(或者调用了非const函数), 编译器就会报错!!!

    • const函数中只能调用const成员函数,在非const函数中,既可以调用const函数,又

    ​ 可以调用非const函数

class Student{public:void setName1(std::string name) const{//m_name = name;std::cout << "m_name = " << m_name << std::endl;//fun1();fun2();}void setName2(std::string name){m_name = name;std::cout << "m_name = " << m_name << std::endl;fun1();fun2();}void fun1(){}void fun2() const {}private:std::string  m_name;};
  • const对象只能调用const成员函数,非const对象能够调用所以的成员函数
 #include<iostream>class Student{public:void setName1(std::string name) const{//m_name = name;std::cout << "m_name = " << m_name << std::endl;//fun1(); error 常函数不能调用普通函数fun2();}void setName2(std::string name){m_name = name;std::cout << "m_name = " << m_name << std::endl;fun1();fun2();}void fun1(){}void fun2() const {}private:std::string  m_name;};int main(){const Student stu1;stu1.setName1("abc");//不生效//stu1.setName2("abc");Student stu2;stu2.setName1("def");//不生效stu2.setName2("qwe");//生效return 0;}
  • 成员函数的常版本与非常版本可构成有效重载,常对象调用常版本,非常对象调用非常版本
 #include<iostream>class Student{public:void fun() const{std::cout << "常版本" << std::endl;}void fun(){std::cout << "非常版本" << std::endl;}private:std::string  m_name;};int main(){Student stu1;stu1.fun();const Student stu2;stu2.fun();return 0;}
http://www.xdnf.cn/news/264979.html

相关文章:

  • list的两种设计
  • MySQL 比较运算符详解
  • 穿越数据森林与网络迷宫:树与图上动态规划实战指南
  • 深拷贝与浅拷贝的核心区别
  • 【unity游戏开发——Animator动画】Animation动画资源节约、优化、编辑修改小技巧
  • 人工智能:如何快速筛选出excel中某列存在跳号的单元格位置?
  • Manus联合创始人:公司产品基于Claude和阿里千问大模型开发
  • Java开发经验——ali编码规范经验总结
  • java面向对象编程【高级篇】之特殊类
  • 【Java多线程】计时器Timer/ScheduledExecutorService的使用
  • mysql主从复制搭建,并基于‌Keepalived + VIP实现高可用
  • MARM:推荐系统中的记忆增强突破
  • C++ - 数据容器之 forward_list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)
  • Python爬虫实战:获取企信网指定公司基本工商数据并分析,为客户选择公司做参考
  • 封装pinia并引入pinia持久化工具(pinia-plugin-persistedstate)
  • HarmonyOS NEXT——DevEco Studio的使用(还没写完)
  • 如何基于HAL库进行STM32开发
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3商用服务开通教程
  • Python 学习
  • 4.29-4.30 Maven+单元测试
  • 【LeetCode Hot100】二分查找篇
  • Swift:重构开发范式的现代编程语言
  • 《高性能MySQL》第1讲:MySQL架构
  • 音视频开发技术总结报告
  • 对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础
  • 3.0/Q1,Charls最新文章解读
  • batch normalization和layer normalization区别
  • 循环缓冲区
  • QNAP Duplicati 备份 123云盘
  • Java接口全面教程:从入门到精通