面向对象三大基本特性,五大基本原则

本文介绍了面向对象编程的三大特性和五大基本原则,包括封装、继承、多态,以及单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

透切理解面向对象三大基本特性是理解面向对象五大基本原则的基础.

三大特性是:封装、继承、多态  

  • 所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
  • 所谓继承,是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
  • 所谓多态,就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

五大基本原则 

  1. 单一职责原则SRP(Single Responsibility Principle)
    是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
  2. 开放封闭原则OCP(Open-Close Principle) 
    一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
  3. 替换原则LSP(the Liskov Substitution Principle) 
    子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。
  4. 依赖原则DIP(the Dependency Inversion Principle) 
    具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
  5. 接口分离原则ISP(the Interface Segregation Principle) 
    模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来。

  • 单一职责原则(SRP)
  • 开放封闭原则(OCP) 
  • 里氏替换原则(LSP) 
  • 依赖倒置原则(DIP) 
  • 接口隔离原则(ISP)
  • 单一职责原则(SRP)

单一职责原则(SRP)
• 一个类应该仅有一个引起它变化的原因(最简单,最容易理解却最不容易做到的一个设计原则)
职员类例子:比如在职员类里,将工程师、销售人员、销售经理这些情况都放在职员类里考虑,其结果将会非常混乱,在这个假设下,职员类里的每个方法都要if else判断是哪种情况,从类结构上来说将会十分臃肿,并且上述三种的职员类型,不论哪一种发生需求变化,都会改变职员类!这个是大家所不愿意看到的!

开放封闭原则(OCP)
• 既开放又封闭,对扩展是开放的,对更改是封闭的!
• 扩展即扩展现行的模块,当我们软件的实际应用发生改变时,出现新的需求,就需要我们对模块进行扩展,使其能够满足新的需求!
更改封闭即是在我们对模块进行扩展时,勿需对源有程序代码和DLL进行修改或重新编译文件!
这个原则对我们在设计类的时候很有帮助,坚持这个原则就必须尽量考虑接口封装,抽象机制和多态技术!

里氏替换原则(LSP)
• 子类可以替换父类并且出现在父类能够出现的任何地方
• 这个原则也是在贯彻GOF倡导的面向接口编程!
在这个原则中父类应尽可能使用接口或者抽象类来实现!
子类通过实现了父类接口,能够替父类的使用地方!
通过这个原则,我们客户端在使用父类接口的时候,通过子类实现!
意思就是说我们依赖父类接口,在客户端声明一个父类接口,通过其子类来实现
这个时候就要求子类必须能够替换父类所出现的任何地方,这样做的好处就是,在根据新要求扩展父类接口的新子类的时候而不影响当前客户端的使用!

依赖倒置原则(DIP)
• 传统的结构化编程中,最上层的模块通常都要依赖下面的子模块来实现,也
称为高层依赖低层!
所以DIP原则就是要逆转这种依赖关系,让高层模块不要依赖低层模块,所以称之为依赖倒置原则!

接口隔离原则(ISP)
• 这个原则的意思是:使用多个专门的接口比使用单个接口要好的多!
这个我有体会,在我实际编程中,为了减少接口的定义,将许多类似的方法都放在一个接口中,最后发现,维护和实现接口的时候花了太多精力,而接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护!

<think>我们正在讨论面向对象编程的五大基本原则,即SOLID原则。根据引用[2]和引用[3],这五大原则分别是: 1. 单一职责原则 (Single Responsibility Principle, SRP) 2. 开放封闭原则 (Open-Closed Principle, OCP) 3. 里氏替换原则 (Liskov Substitution Principle, LSP) 4. 接口隔离原则 (Interface Segregation Principle, ISP) 5. 依赖倒置原则 (Dependency Inversion Principle, DIP) 接下来,我们将逐一解释每个原则,并给出简单的代码示例(使用Java语言)以帮助理解。 注意:引用[4]中也提到了开放封闭原则和里氏替换原则,我们可以参考。 由于用户要求使用中文回答,并且要求生成相关问题,我们将按照以下结构组织答案: 1. 对每个原则进行定义和解释。 2. 给出一个简单的代码示例(如果适用)。 3. 在最后生成相关问题。 注意:在代码示例中,我们使用Java,因为引用中提到了Java面向对象五大基本原则(引用[3])。 开始回答:</think>### 面向对象编程的五大基本原则(SOLID原则面向对象编程的五大基本原则统称为 **SOLID 原则**,由 Robert C. Martin 提出,旨在提升代码的可维护性、可扩展性和灵活性。以下是详细解析: --- #### 1. **单一职责原则(Single Responsibility Principle, SRP)** - **核心**:一个类只负责**一项功能**或一个变化原因[^2][^3]。 - **作用**:避免"上帝类",降低耦合度,提高可读性。 - **示例**: ```java // 违反原则:同时处理用户数据和邮件发送 class UserManager { void saveUser(User u) { ... } void sendEmail(User u) { ... } // 应拆分到单独类 } // 遵循原则:拆分职责 class UserRepository { void saveUser(User u) { ... } } class EmailService { void sendEmail(User u) { ... } } ``` --- #### 2. **开放封闭原则(Open-Closed Principle, OCP)** - **核心**:软件实体应对**扩展开放**,对**修改关闭**[^3][^4]。 - **实现**:通过抽象(接口/抽象类)定义规范,通过子类实现扩展。 - **示例**: ```java interface PaymentProcessor { void processPayment(); // 抽象定义 } class CreditCardProcessor implements PaymentProcessor { @Override void processPayment() { ... } // 扩展实现 } class PayPalProcessor implements PaymentProcessor { @Override void processPayment() { ... } // 新增支付方式无需修改接口 } ``` --- #### 3. **里氏替换原则(Liskov Substitution Principle, LSP)** - **核心**:子类必须能**完全替换父类**而不破坏程序逻辑[^3][^4]。 - **规则**: - 子类不强化父类前置条件(如不缩小输入范围)。 - 子类不弱化父类后置条件(如不扩大输出范围)。 - **示例**: ```java class Bird { void fly() { ... } // 父类方法 } // 正确:企鹅不应继承Bird,因无法fly() class Penguin {} // 避免违反LSP // 正确设计:拆分飞行能力 interface Flyable { void fly(); } class Sparrow implements Flyable { ... } class Penguin {} // 不实现Flyable ``` --- #### 4. **接口隔离原则(Interface Segregation Principle, ISP)** - **核心**:客户端不应依赖**不需要的接口方法**[^2][^3]。 - **实践**:将庞大接口拆分为**多个小接口**,避免"接口污染"。 - **示例**: ```java // 违反原则:多功能接口 interface Worker { void code(); void design(); void test(); } // 程序员被迫实现无关的design()和test() // 遵循原则:拆分接口 interface Coder { void code(); } interface Designer { void design(); } interface Tester { void test(); } class Developer implements Coder, Tester { ... } // 按需实现 ``` --- #### 5. **依赖倒置原则(Dependency Inversion Principle, DIP)** - **核心**: - 高层模块不依赖低层模块,二者依赖**抽象**。 - 抽象不依赖细节,细节依赖抽象[^3][^4]。 - **实现**:通过依赖注入(如构造函数注入)解耦。 - **示例**: ```java // 违反原则:高层直接依赖具体数据库 class ReportService { private MySQLDatabase db; // 紧耦合 void generateReport() { db.query(...); } } // 遵循原则:依赖抽象接口 interface Database { void query(); } class MySQLDatabase implements Database { ... } class ReportService { private Database db; // 依赖抽象 ReportService(Database db) { this.db = db; } // 依赖注入 void generateReport() { db.query(); } } ``` --- ### SOLID 原则关系总结 | 原则 | 缩写 | 核心目标 | 关键实现 | |------|------|----------|----------| | 单一职责 | SRP | 功能聚焦 | 拆分大类 | | 开放封闭 | OCP | 扩展友好 | 抽象隔离 | | 里氏替换 | LSP | 继承安全 | 子类兼容父类 | | 接口隔离 | ISP | 接口精简 | 拆分胖接口 | | 依赖倒置 | DIP | 解耦依赖 | 面向抽象编程 | > 💡 **SOLID 的价值**: > 这些原则共同解决了软件设计的**腐化问题**(如代码僵化、脆弱性、耦合度过高)。例如: > - 遵循 DIP 和 OCP 可使系统轻松切换数据库(如 MySQL → MongoDB)[^4]; > - 遵守 LSP 和 ISP 能避免无效继承和接口冗余[^3]。 --- ### 相关问题 1. 如何通过**依赖注入框架**(如 Spring)实现依赖倒置原则? 2. 违反里氏替换原则会导致哪些具体问题?请举例说明。 3. 在微服务架构中,接口隔离原则如何指导 API 设计? 4. 开放封闭原则与设计模式(如策略模式、装饰器模式)有何关联? [^1]: 面向对象——五大基本原则 [^2]: 面向对象及其五大基本编程原则 [^3]: java面向对象五大基本原则 [^4]: 面向对象三大基本特征和五大基本原则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值