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

封装,继承,多态

下面我将分别对它们进行详细解释,包括其特点、具体含义以及在项目中的应用


一、封装

1. 特点

数据隐藏:对象的内部状态(数据)对外部是不可见的,外部不能直接访问和修改。
访问控制:通过提供有限的、受控的接口(通常是公共方法)来与对象进行交互。
模块化:将数据和对数据的操作捆绑在一起,形成一个独立的单元(类),降低了代码的耦合度。
易于维护:当类的内部实现需要改变时,只要不修改其公共接口,就不会影响到依赖该类的其他代码。

2. 具体含义

封装就像使用一个遥控器来控制电视。你不需要知道电视内部的电路板、显像管是如何工作的(这些是隐藏的数据),你只需要通过遥控器上的几个按钮(公共方法,如powerOn()changeChannel())来操作电视即可。遥控器封装了电视复杂的内部细节,只为你提供简单、安全的操作界面。

在代码中,封装通常通过以下方式实现:

将成员变量(字段)设为 private:这是实现数据隐藏的关键,确保外部代码不能直接访问这些变量。
提供 public 的 getter 和 setter 方法:作为外部访问和修改私有变量的唯一途径。在这些方法中,可以添加逻辑进行数据校验、权限控制等。

示例代码:

// 一个封装良好的 User 类
public class User {// 1. 将数据成员设为 private,实现数据隐藏private String username;private String password;private int age;// 2. 提供公共的构造器和方法来操作数据public User(String username, String password, int age) {this.username = username;setPassword(password); // 通过 setter 方法设置密码,可以在这里进行加密this.age = age;}// 3. 提供公共的 getter 方法public String getUsername() {return username;}public int getAge() {return age;}// 4. 提供公共的 setter 方法,可以在其中添加逻辑public void setAge(int age) {if (age > 0) { // 数据校验this.age = age;} else {System.out.println("年龄必须大于0");}}// 密码不应该提供 getter,修改时通过加密逻辑public void setPassword(String password) {// 这里可以添加密码加密逻辑this.password = password;}
}
3. 项目中的应用

实体类:如 User, Product, Order 等。它们的内部状态(如用户名、价格、订单状态)被封装起来,只能通过特定的方法进行修改,保证了数据的完整性。
服务层:服务类封装了复杂的业务逻辑。例如,一个 OrderService 会封装创建订单、取消订单、支付订单等一系列操作,外部调用者只需调用 orderService.createOrder(),而无需关心订单创建背后数据库如何操作、如何计算折扣等细节。
配置管理:一个 AppConfig 类可以封装所有应用程序的配置信息(如数据库URL、API密钥),外部代码通过 config.getDbUrl() 来获取,而不是直接访问一个静态字符串。

二、继承

1. 特点

实体类:如 User, Product, Order 等。它们的内部状态(如用户名、价格、订单状态)被封装起来,只能通过特定的方法进行修改,保证了数据的完整性。
服务层:服务类封装了复杂的业务逻辑。例如,一个 OrderService 会封装创建订单、取消订单、支付订单等一系列操作,外部调用者只需调用 orderService.createOrder(),而无需关心订单创建背后数据库如何操作、如何计算折扣等细节。
配置管理:一个 AppConfig 类可以封装所有应用程序的配置信息(如数据库URL、API密钥),外部代码通过 config.getDbUrl() 来获取,而不是直接访问一个静态字符串。

2. 具体含义

继承就像生物学中的“父子”关系。子类(派生类)会自动拥有父类(基类)的所有特征和行为,并且可以在此基础上扩展自己的新特征和行为,或者重写父类已有的行为。

示例代码:

// 父类:动物
public class Animal {public String name;public Animal(String name) {this.name = name;}public void eat() {System.out.println(name + " 正在吃东西。");}
}// 子类:狗,继承自动物
public class Dog extends Animal {// Dog 自动继承了 name 属性和 eat() 方法public Dog(String name) {// 必须调用父类的构造器来初始化继承的属性super(name);}// Dog 独有的方法public void bark() {System.out.println(name + " 在汪汪叫。");}// 可以重写父类的方法@Overridepublic void eat() {System.out.println(name + " 在吃狗粮。");}
}// 使用
public class Main {public static void main(String[] args) {Dog myDog = new Dog("旺财");myDog.eat(); // 调用的是重写后的方法myDog.bark(); // 调用自己的独有方法}
}
3. 项目中的应用

构建通用框架:创建一个通用的 BaseController 或 BaseService,包含所有控制器/服务共用的日志记录、异常处理、权限校验等方法。然后让具体的控制器(如 UserController, ProductController)去继承它,从而复用这些通用功能。
实体类分层:可以创建一个 BaseEntity 抽象类,包含 id, createTime, updateTime 等所有实体共有的字段。然后让 User, Product 等实体类去继承它。
处理不同类型的数据:在支付系统中,可以有一个 Payment 父类,然后有 AlipayPayment, WechatPayment, CreditCardPayment 等子类。它们都实现了 pay() 方法,但内部逻辑不同。

三、多态

1. 特点

同一接口,不同实现:同一个方法调用,作用于不同的对象,会产生不同的行为。
提高代码的灵活性和可扩展性:可以编写更通用、更灵活的代码,而无需关心具体对象是什么类型。
降低耦合度:代码依赖于抽象(如接口或抽象类),而不是具体的实现类。

2. 具体含义

多态的字面意思是“多种形态”。在编程中,它意味着一个类型的变量可以引用多种不同类型的对象,并且在调用方法时,程序会根据实际运行时的对象类型来决定调用哪个方法。

实现多态需要三个条件:

  1. 继承:必须有类之间的继承关系。
  2. 重写:子类必须重写父类的方法。
  3. 父类引用指向子类对象Parent p = new Child();

示例代码:

// 继承关系(同上)
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("汪汪");}
}class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("喵喵");}
}// 测试多态
public class PolymorphismDemo {public static void main(String[] args) {// 1. 父类引用指向子类对象Animal myDog = new Dog();Animal myCat = new Cat();// 2. 调用同一方法,但产生不同行为// 编译器看的是声明类型(Animal),运行时JVM看的是实际对象类型(Dog/Cat)myDog.makeSound(); // 输出: 汪汪myCat.makeSound(); // 输出: 喵喵// 创建一个可以处理所有动物的数组Animal[] animals = new Animal[3];animals[0] = new Dog();animals[1] = new Cat();animals[2] = new Animal();// 遍历并调用,代码非常通用和灵活for (Animal animal : animals) {animal.makeSound();}}
}
3. 项目中的应用

策略模式:这是多态最经典的应用场景。假设一个电商系统需要支持多种促销活动,如 CouponDiscount(优惠券折扣)、GroupBuyDiscount(团购折扣)等。它们都实现一个 DiscountStrategy 接口,该接口有一个 calculate() 方法。
public interface DiscountStrategy {
double calculate(double originalPrice);
}
在购物车类中,可以持有一个 `DiscountStrategy` 的引用,而不是具体的折扣类。当需要计算折扣时,只需调用 `strategy.calculate()`。切换促销活动时,只需传入不同的策略实现类即可,购物车代码完全不需要修改。

模板方法模式:定义一个算法的骨架,而将一些步骤延迟到子类中。例如,一个 DataProcessor 抽象类定义了 process() 方法,其中包含 readData(), processData(), saveData() 等步骤。readData() 和 saveData() 可以有默认实现,而 processData() 是抽象方法。具体的处理器(如 JsonDataProcessor, XmlDataProcessor)去继承并实现 processData()。
事件监听器:在GUI编程(如Java Swing)或Web开发中,按钮点击事件、鼠标移动事件等都是通过多态实现的。你为按钮添加一个 ActionListener,这个监听器就是一个对象。当点击事件发生时,框架会调用监听器对象的 actionPerformed() 方法,而不管这个监听器具体是什么类型。
依赖注入/框架设计:许多框架(如Spring)的核心思想就是依赖注入。你让业务类依赖于一个接口(如 Repository),而不是一个具体的实现(如 JdbcRepository)。在运行时,框架会注入一个具体的实现对象。这使得业务逻辑与数据访问技术完全解耦,可以轻松地在MySQL和MongoDB之间切换,而无需改动业务代码。

总结

特性封装继承多态
核心思想数据隐藏,保护对象内部状态代码复用,建立 is-a 关系同一接口,不同实现
解决的问题如何保护数据、降低耦合如何复用代码、建立结构如何提高灵活性、降低耦合
关系独立,是OOP的基础是多态实现的前提是封装和继承的最终体现
项目中的角色定义类的边界和行为构建代码的骨架和层次实现灵活、可扩展的业务逻辑

在实际项目中,这三大特性是相辅相成、密不可分的。通过封装来保护数据,通过继承来构建代码结构,最终利用多态来实现高内聚、低耦合、易于扩展和维护的软件系统。

http://www.dtcms.com/a/337774.html

相关文章:

  • 【CV 目标检测】Fast RCNN模型③——模型训练/预测
  • day44_2025-08-18
  • iOS 性能监控全流程实践,从开发到上线的多工具组合方案
  • RabbitMQ ,消息进入死信交换机
  • QT 字节大小端转序方法
  • Qt5基础控件详细讲解
  • VSCode REST Client 使用总结
  • 【力扣-轮转数组 Java / Python】
  • leetcode415. 字符串相加
  • 【论文阅读】-《HopSkipJumpAttack: A Query-Efficient Decision-Based Attack》
  • Jenkins全链路教程——Jenkins调用Maven构建项目
  • 北京朝阳公园——夏日清凉来袭
  • 第7节 神经网络
  • 登上Nature!清华大学光学神经网络研究突破
  • FastAPI + React:现代 Web 前后端分离开发的全栈实践指南
  • 【原理】Unity GC 对比 C# GC
  • 电竞酒店和高校宿舍对AI云电竞游戏盒子的需求有什么不同?
  • 静态资源保存插件横评:Save All Resources 与 ResourcesSaverExt 哪个更适合你?
  • 无人机基础知识
  • 测绘级组合导航如何重新定义大型无人机的高精度导航标准?
  • 用本地代理 + ZIP 打包 + Excel 命名,优雅批量下载跨域 PDF
  • PDF转图片需要用到什么技术?苹果手机怎样将PDF转为jpg?
  • HTML/CSS 实战知识点总结:从基础到常用效果全解析
  • 2025 世界机器人大会启示录:机构学 × AI × 视频链路的融合之路
  • 【低空安全】低空安全简介
  • 27.Linux 使用yum安装lamp,部署wordpress
  • Kafka 零拷贝(Zero-Copy)技术详解
  • 【学习嵌入式-day-27-进程间通信】
  • 开放最短路径优先协议
  • Read View 在 MVCC 里如何工作的?