首页 > 编程语言 >面向对象编程,看这篇就够了

面向对象编程,看这篇就够了

时间:2023-12-12 18:44:21浏览次数:77  
标签:需要 可以 接口 我们 这篇 面向对象编程 代码

一、面向对象编程的概念

面向对象编程,是一种程序设计范式,也是一种编程语言的分类。它以对象作为程序的基本单元,将算法和数据封装其中,程序可以访问和修改对象关联的数据。这就像我们在真实世界中操作各种物体一样,比如我们可以打开电视、调整音量、切换频道,而不需要知道电视的内部如何工作。同样,在面向对象编程中,我们可以操作对象,而不需要关心对象的内部结构和实现。

面向对象编程的主要组成部分是类和对象。类是一组具有相同属性和功能的对象的抽象,就好比我们说的“汽车”这个概念,它具有颜色、型号、速度等属性,有启动、加速、刹车等功能。而对象则是类的实例,它是具体的,就像你家那辆红色的奔驰车,它就是汽车这个类的一个实例。

二、面向对象编程的特性

面向对象编程有三大特性,封装、继承和多态。

1. 封装

封装是把客观事物封装成抽象的类,并隐藏实现细节,使得代码模块化。比如,我们可以把“汽车”这个客观事物封装成一个类,这个类有颜色、型号等属性,有启动、加速、刹车等方法,而这些属性和方法的具体实现则被隐藏起来,使用者只需要知道这个类有哪些属性和方法,不需要知道这些方法是如何实现的。

2. 继承

继承是面向对象编程的另一个重要特性,它提供了一种无需重新编写,使用现有类的所有功能并进行扩展的能力。比如,我们可以定义一个“电动车”类,它继承了“汽车”类,就自动拥有了“汽车”类的所有属性和方法,比如颜色、型号等属性,启动、加速、刹车等方法,然后我们还可以在“电动车”类上增加一些新的属性和方法,比如电池容量、充电方法等。

3. 多态

多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。比如,我们定义了一个“汽车”类,它有一个“启动”方法,然后我们又定义了一个“电动车”类,它继承了“汽车”类,也有一个“启动”方法,但是“电动车”类的“启动”方法的实现可能与“汽车”类的不同,这就是多态。

三、面向对象编程的理念

面向对象编程有两个主要的理念,基于接口编程和组合优于继承。

1. 基于接口编程

基于接口编程的理念是,使用者不需要知道数据类型、结构和算法的细节,只需要知道调用接口能够实现功能。这就像我们使用电视遥控器一样,我们不需要知道遥控器内部的电路设计和工作原理,只需要知道按哪个按钮可以打开电视,按哪个按钮可以调节音量。

基于接口编程有很多好处,这里简单列几条。

首先,基于接口编程可以提高代码的灵活性。因为我们的代码不依赖于具体的实现,所以当实现变化时,我们的调用代码不需要做任何修改。比如有一个程序需要读取数据,数据可能来自于数据库、文件或者网络,无论数据来自哪里,调用方只访问“数据读取”接口,实现可以根据场景任意调整。

其次,基于接口编程可以提高代码的可测试性。因为接口只是一个规范,没有具体的实现,所以我们可以方便地为接口创建模拟对象(Mock Object),这样就可以在没有实际环境的情况下进行单元测试。比如说,我们可以创建一个模拟的“数据读取”接口,让它返回一些预设的数据,然后我们就可以在没有数据库或者文件的情况下测试我们的代码。

最后,基于接口编程也可以提高代码的可读性。因为接口清晰地定义了功能,所以只要看接口,就可以知道代码应该做什么,而不需要关心代码是怎么做的。这就像我们使用电视遥控器,我们不需要知道遥控器是怎么工作的,只需要知道按这个按钮可以换台,按那个按钮可以调节音量。

使用接口有利于抽象、封装和多态。

2. 组合优于继承

尽管继承可以使我们更容易地重用和扩展代码,但是如果继承层次过深、继承关系过于复杂,就会严重影响代码的可读性和可维护性。比如我们修改了基类,就可能影响到继承它的子类,这会增加迭代的风险。因此,我们更倾向于使用组合而不是继承。比如,我们可以定义一个“电动车”类,它包含“电池系统”、“制动系统”、“车身系统”、“转向系统”等组件,而不是继承“汽车”类。

这里我们再列举下组合的几个好处:

首先,组合可以让我们的代码更加灵活。因为我们可以随时添加、删除或者替换组件,而不需要修改组件的内部实现。比如,如果我们想要改变汽车的发动机,只需要换掉发动机这个组件就可以了,而不需要修改汽车或者发动机的代码。

其次,组合可以让我们的代码更容易理解。因为每个组件都是独立的,有明确的功能,所以我们可以分别理解和测试每个组件,而不需要理解整个系统。

最后,组合可以减少代码的复杂性。因为我们不需要创建复杂的类层次结构,所以我们的代码会更简单,更易于维护。

总的来说,“组合优于继承”是一种编程实践,它鼓励我们使用更简单、更灵活的组合,而不是更复杂、更脆弱的继承。这并不是说继承是坏的,而是说在许多情况下,组合可能是一个更好的选择。

3.控制反转代码示例

具体到编程中,很多同学可能使用过控制反转或者依赖注入,控制反转就是一种基于接口的组合编程思想。在传统的编程模式中,我们通常是在需要的地方创建对象,然后调用对象的方法来完成一些任务。但是在使用了控制反转之后,对象的创建和管理工作不再由我们自己控制,而是交给了一个外部的容器(也就是所谓的平台),我们只需要在需要的地方声明我们需要什么,然后容器会自动为我们创建和注入需要的对象。这就是所谓的依赖注入(Dependency Injection,简称DI),它是实现控制反转的一种方法。

为了让大家更好理解依赖注入,我这里贴一个Java的例子,程序基于 Spring Boot 框架。

在这个例子中,我们有一个 MessageService 接口和一个实现类 EmailService。然后我们有一个MessageClient类,它依赖于MessageService来发送消息。

首先,定义一个MessageService接口:

public interface MessageService {
    void sendMessage(String message, String receiver);
}

然后,创建实现类,在Spring Boot中,我们可以使用@Component或@Service等注解来让Spring自动创建Bean。然后在需要注入的地方,使用@Autowired注解来自动注入Bean。

我们将MessageService的实现类标记为@Service:

@Service
public class EmailService implements MessageService {
    public void sendMessage(String message, String receiver) {
        System.out.println("Email sent to " + receiver + " with Message=" + message);
    }
}

我们在MessageClient中使用@Autowired来注入MessageService:

@Component
public class MessageClient {
    private MessageService messageService;

    @Autowired
    public MessageClient(MessageService messageService) {
        this.messageService = messageService;
    }

    public void processMessage(String message, String receiver){
        this.messageService.sendMessage(message, receiver);
    }
}

最后,在主程序中,我们可以直接获取MessageClient的Bean,而不需要手动创建:

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
        MessageClient emailClient = context.getBean(MessageClient.class);
        emailClient.processMessage("Hello", "[email protected]");
    }
}

在这个例子中,Spring Boot会自动扫描@Service和@Component注解的类,并创建对应的Bean。然后在需要注入的地方,Spring Boot会自动找到对应的Bean并注入。

控制反转是一种非常强大的设计原则,它可以帮助我们写出更灵活、更易于维护和测试的代码。如果你还没有尝试过,我强烈建议你试试!

四、面向对象编程的原则

面向对象编程有五个基本原则,也被称为SOLID原则。

1. 单一原则

单一原则是指一个类应该仅具有只与他职责相关的东西,这样可以降低类的复杂度,提高可读性和可维护性。

这个原则就像是你在厨房里做饭,你有各种各样的厨具,每个厨具都有它特定的用途,比如刀用来切菜,锅用来煮食物,勺子用来搅拌。你不会用刀去搅拌,也不会用勺子去切菜。这样每个厨具都只负责一项任务,使得厨房的运作更加顺畅。

2. 开闭原则

开闭原则是指软件中的类、属性和函数对扩展是开放的,对修改是封闭的。这样可以避免对原有代码的修改导致的很多工程工作。

这个原则就像是你的房子,你可以在房子里面添加更多的家具,比如椅子、桌子、床等,但你不会去改变房子的结构,比如拆掉墙壁或者增加门窗。这样你的房子对于添加家具是开放的,对于修改结构是关闭的。

在计算机体系中,最符合开闭原则的就是冯诺依曼体系架构,在这个架构中,CPU是封闭的、稳定的,然后通过IO操作对外开放,支持各种无穷无尽的输入输出设备。这是开闭原则的最好最基础的体现。

3. 里氏替换原则

里氏替换原则是指子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。这样可以让高层次模块能够依赖抽象类,而不是具体的实现。

这个原则就像是你的电视遥控器,无论你的电视是老款的CRT电视,还是新款的LED电视,你都可以用同一个遥控器来控制。这是因为所有的电视都遵循了同样的接口,即遥控器可以发送的信号。所以你可以用新的电视来替换老的电视,而不需要改变遥控器。

4. 接口隔离原则

接口隔离原则是指类间的依赖关系应该建立在最小的接口之上,这样可以减少类间的耦合度。

举个例子,假设我们有一个Animal接口,它包含了eat(), sleep(), fly()等方法。现在我们要设计一个Dog类来实现这个接口,但是狗并不能飞,所以fly()方法对于Dog类来说是不需要的。如果我们按照接口隔离原则来设计,那么我们可以将Animal接口拆分为AnimalBasic(包含eat()和sleep()方法)和AnimalFly(包含fly()方法)两个接口,然后让Dog类只实现AnimalBasic接口,这样就避免了实现不需要的方法。

5. 依赖反转原则

依赖反转原则是指高层次模块不应该依赖于低层次模块的具体实现,两者都应该依赖其抽象。这样可以提高代码的可扩展性。

举个例子,假设我们有一个高级模块HighLevelModule和一个低级模块LowLevelModule。HighLevelModule直接依赖于LowLevelModule的具体实现。现在,如果我们遵循依赖反转原则,我们可以定义一个抽象的接口AbstractModule,然后让HighLevelModule依赖于AbstractModule,同时让LowLevelModule也实现AbstractModule。这样,无论是HighLevelModule还是LowLevelModule,它们都只依赖于抽象,而不再直接依赖于对方的具体实现。这样就可以提高代码的可扩展性和可维护性。

五、面向对象编程的优缺点

面向对象编程的优点主要有两个:

  • 一是能和真实的世界交相呼应,符合人的直觉。对象是基于真实世界实体的抽象,比如学生、书籍、车辆等,这些对象都有其属性(如学生的名字、年龄)和行为(如学生的学习、阅读)。这样的设计方式使得我们能够更直观地理解和操作代码,因为它与我们日常生活中的理解方式是一致的。
  • 二是代码的可重用性、可扩展性和灵活性很好。这主要得益于OOP的几个主要特性,包括封装、继承和多态。封装可以隐藏对象的内部实现,只暴露出必要的接口,这样可以防止外部的不恰当操作。继承允许我们创建子类来复用和扩展父类的功能,这大大提高了代码的可重用性。多态则允许我们使用同一个接口来操作不同的对象,这提高了代码的灵活性。

然而,面向对象编程也并非完美,它也有一些缺点,比如:

  • 首先,由于代码需要通过对象来抽象,这就增加了一层“代码粘合层”,也就是我们需要创建对象、管理对象的生命周期、处理对象之间的关系等,这使得代码变得更加复杂。对于一些简单的问题,使用面向对象编程可能会有点“杀鸡用牛刀”。
  • 其次,面向对象编程中的对象通常都有一些内部状态,而这些状态在并发环境下需要被正确地管理,否则就可能会出现数据不一致、死锁等问题。比如,如果两个线程同时操作同一个对象,而这个对象的状态没有被正确地保护,那么就可能会出现数据不一致的问题。

总的来说,面向对象编程是一种强大而灵活的编程范式,它可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性,这使得它特别适合用在大型工程项目中。然而,我们也需要注意其可能带来的问题,尤其是在并发和复杂系统中。

关注萤火架构,技术提升不迷路!

标签:需要,可以,接口,我们,这篇,面向对象编程,代码
From: https://www.cnblogs.com/bossma/p/17897584.html

相关文章

  • Java第七课_面向对象编程
    1.面向对象的编程对象publicclassPractice01{publicstaticvoidmain(String[]args){/*面向对象的编程,将一切事项都视为对象.对象用类来描述,过程在类里实现.使用时只需要调用类,不需要再考虑如何实现.将对象的共同特征进行......
  • CRM系统有哪些管理客户的功能?这篇文章告诉您
      客户管理可以理解为企业收集并利用客户信息,满足客户的需求,从而提升客户价值的过程。CRM系统一直被誉为客户管理的“神器”,下面我们就来说说CRM系统有哪些功能可以管理客户?1、客户信息管理CRM可以帮助企业收集客户的基本信息、需求偏好、购买记录等,并对这些信息进行深入的......
  • #yyds干货盘点#深入了解Python类与面向对象编程
    类与对象的概念1.什么是类?类是一种用户自定义的数据类型,用于描述对象的属性和行为。它是对象的模板,定义了对象的结构。2.创建类使用class关键字来创建类。示范如何定义一个类,包括类名、属性和方法的定义。classDog:def__init__(self,name,breed):self.name=nam......
  • 使用Java实现面向对象编程 第八章 File IO 总结笔记
    java里操作文件1.第一步一定是获得这个文件(获得的文件,你是无法解析获得里面的内容,约等于获得冰。你只能知道大小颜色等。外表能够获取信息.)。2.第二步获得这个文件将这个文件转换成流。然后从这个io流里读取数据io流里又分为字符流(专门处理文字)字节流(专门处理2进制等文件)3.......
  • SaaS软件哪个好?这篇文告诉你
    引言:在当今数字化时代,SaaS(SoftwareasaService)软件的崛起为企业提供了高效、灵活和可扩展的解决方案。SaaS软件以其云端部署、按需订阅和无需繁琐的安装和维护而备受欢迎。本文将介绍三款备受推崇的SaaS软件:Helplook、Salesforce和Slack,并探讨它们的特点、优势以及适用场景,帮助你......
  • C++入门:掌握基本语法和面向对象编程
    C++入门:掌握基本语法和面向对象编程C++是一种通用的、高级的编程语言,广泛应用于开发各种应用程序。对于初学者来说,掌握C++的基本语法和面向对象编程是一个重要的起点。本篇博客将介绍C++的基本语法和面向对象编程的基本概念。了解C++的基本语法注释在C++中,你可以使用两种方式添加注......
  • 软件测试/人工智能|什么是LangChain,这篇文章告诉你
    简介随着人工智能和自然语言处理技术的飞速发展,我们越来越依赖机器来理解、生成和处理语言。在这样的背景下,LangChain应运而生,它旨在构建一个高效、强大的语言处理生态系统,将人类语言与智能技术紧密相连。LangChain的核心概念LangChain是一个基于区块链技术的语言处理平台,它利用去......
  • 我试图通过这篇文章告诉你,什么是神奇的泛化调用。
    你好呀,我是歪歪。关于RPC调用,大家肯定都是比较熟悉的了,就是在微服务架构下解决系统间通信问题的一个玩意。其中的典型代表之一就是Dubbo了:在微服务架构下,我们针对某个RPC接口,我们一般有两个角色。服务消费者(DubboConsumer),发起业务调用或RPC通信的Dubbo进程服......
  • 这篇保证你彻底搞懂Java NIO的Selector事件选择器
     Selector提供选择执行已经就绪的任务的能力,使得多元I/O成为可能,就绪选择和多元执行使得单线程能够有效率地同时管理多个I/Ochannel。C/C++许多年前就已经有select()和poll()这两个POSIX(可移植性操作系统接口)系统调用可供使用。许多os也提供相似的功能,但对Java程序......
  • 企业知识库?这篇文章给你讲清楚!
    在当今商务环境中,企业面对着大量信息和知识的流动。这些信息和知识散布在各个部门、团队甚至个人之间,难以进行有效的整合和利用。然而,企业知识库的出现解决了这一问题。它提供了一个统一的平台,将分散的信息聚集到一个集中的数据库中,并通过搜索、分类、标签等功能使用户能够快速定位......