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

封装、继承、多态的含义及其项目应用

一、封装 

1.含义

具体来说,封装就是将属性和操作方法捆绑在一起,形成一个独立的"类",并通过访问控制(如private、public 等修饰符)限制外部对内部的直接操作,只允许通过预先定义来访问或修改数据

其核心思想是:"隐藏内部细节,暴露必要接口”。

2.目的

(1)保护数据安全性,防止外部随意修改内部数据,避免数据被错误篡改

(2)降低耦合度:外部只需用就行,不用关注内部是如何实现的,即使用时,即使封装类内部逻辑发生了变化,只要接口不变,外部代码就无需改变

(3)提高代码可维护性:内部逻辑集中在类中,修改时只需要调整类的内部,不影响外部使用

3.在项目的应用场景:

(1)实体类(Form/VO)的封装

  当我们写项目时,接口文档中显示着需要我们接受或者返回的参数,这些参数

 示例:

### 人脸采集URL```
POST /sys/person/addPerson
```参数```
{"personId": 98,"extName": "png","fileBase64": "iVBORw0KGgoAAAANSUhEUgAAAJsAAAC4CAYAAAD0WZ4UAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJ8pt02jBn6wUmcy/39/xgi2nSFeQGzAAAAAElFTkSuQmCC"
}
```返回```
{"msg": "操作成功","code": 200
}
```### 删

这是完成人脸采集的接口内容,我们可以看到要从前端接受的参数为:

"personId": 98,"extName": "png","fileBase64": "iVBORw0KGgoAAAANSUhEUgAAAJsAAAC4CAYAAAD0WZ4UAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJ8pt02jBn6wUmcy/39/xgi2nSFeQGzAAAAAElFTkSuQmCC"

但是我们的我们对应的项目根本没有对应的实体类,此时我们就可以封装一个新的实体类FORM

package com.qcby.model.entity;import lombok.Data;@Data
public class FaceForm {private Integer personId;private String extName;private String fileBase64;
}

注:@Data注解已经完成了 set和get方法

应用价值:

当数据传过来时 我们可以用Data注解中的set方法设置创建类的属性的值,这样的封装类应用起来既方便又安全,不用我们在外部一个一个设置属性了。

(2)工具类的封装

将通用功能(如日期处理、加密处理)封装成工具类,隐藏实现细节,只是暴露静态方法供外部调用。

示例:

public class DateUtils {// 私有构造方法,禁止外部创建实例(工具类无需实例化)private DateUtils() {}// 公开静态方法(暴露接口)public static String format(Date date, String pattern) {// 内部实现(隐藏细节,比如用 SimpleDateFormat 处理)SimpleDateFormat sdf = new SimpleDateFormat(pattern);return sdf.format(date);}public static Date parse(String dateStr, String pattern) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat(pattern);return sdf.parse(dateStr);}
}

应用价值:

(1)外部只需要调用 DateUtils.format(...)即可格式化日期,无需关心SimpleDateFormat的用法和线程安全问题

(2)如果未来想替换为DateTimeFormatter,只需要修改工具类内部,外部调用代码无需变动。

(3)服务层的封装

在分层架构中(SpringBoot)中,Service层封装业务逻辑,隐藏复杂的处理流程对外提供简洁的接口。

示例:

在业务层实现动态路由业务逻辑:

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuEntity> implements MenuService {  @AutowiredMenuMapper menuMapper;@Overridepublic List<MenuRouterVO> getMenuRouterVOById(Integer UserId) {List<MenuEntity> menulist = menuMapper.getMenuById(UserId);return getMenuRouterVOList(menulist);}private List<MenuRouterVO> getMenuRouterVOList(List<MenuEntity> menulist) {//创建一个大的集合是为了能封装最后的数据List<MenuRouterVO> menuRouterVOList = new ArrayList<>();for (MenuEntity menu : menulist) {if (menu.getParentId() == 0) {//再创建一个新的MenuRouterVO类MenuRouterVO menuRouterVO = new MenuRouterVO();//将parent_id为0的菜单信息(父级菜单对象)赋值BeanUtils.copyProperties(menu, menuRouterVO);//再赋值剩下的部分MetaVo metaVo = new MetaVo();metaVo.setTitle(menu.getName());metaVo.setIcon(menu.getIcon());menuRouterVO.setMeta(metaVo);//Menu和Menuvo都装好了,现在我们去寻找父级菜单的孩子属性List<ChildrenMenuRouterVO> children = new ArrayList<>();for (MenuEntity child : menulist) {if (child.getParentId() == menu.getMenuId()) {ChildrenMenuRouterVO childMenuRouterVO = new ChildrenMenuRouterVO();BeanUtils.copyProperties(child, childMenuRouterVO);childMenuRouterVO.setMeta(metaVo);MetaVo metaVo1 = new MetaVo();metaVo1.setTitle(child.getName());metaVo1.setIcon(child.getIcon());childMenuRouterVO.setMeta(metaVo1);children.add(childMenuRouterVO);}}menuRouterVO.setChildren(children);menuRouterVOList.add(menuRouterVO);}}return menuRouterVOList;}
}

应用价值:

封装好之后我们只需要在表现层(Controller层) 引入MenuService类属性

@Autowiredprivate MenuService menuService

再 调用menuService.getMenuRouterVOById(Integer UserId)方法就可以得到相应的数据

二、继承

1.核心思想

继承的核心思想是:"复用已有类的属性和方法,并在此基础上扩展新功能”

2.核心目的:

(1)代码复用:避免重复编写相同的代码(父类定义通用逻辑,子类直接复用)

(2)逻辑扩展:再父类基础上添加新功能,实现"特殊化"。

(3)多态基础:子类对象可以被当作父类对象使用,为多态(同一操作在不同对象有不同表现)提供支持

3.在项目的应用场景:

(1)提取通用逻辑,减少重复代码

当多个类存在相同的属性或方法时,将这些共性提取到父类中,子类继承父类即可复用,无需重复编写。

示例:

在电商系统中,"商品"可分为"实体商品"(如手机)和"虚拟商品"(如充值卡),它们有共性(名称、价格、库存),也有差异(实体商品有重量,虚拟商品有有效期)。

//提取共性
public class Product{//protected 保证子类可以访问protected String name;//商品名称protected Double price;//价格protected int stock;//库存 //共性方法:计算总价public double calculateTotal(int quantity){return price*quantity;}//其他共性方法(如设置名称、获取价格等)public void setName (String name){this.name=name;}public double getPrice(){return price;}}
// 子类1:实体商品(继承父类,添加特有属性)
public class PhysicalProduct extends Product {private double weight; // 特有属性:重量// 特有方法:计算运费public double calculateShippingFee() {return weight * 0.5; // 假设每公斤0.5元运费}
}// 子类2:虚拟商品(继承父类,添加特有属性)
public class VirtualProduct extends Product {private String expiryDate; // 特有属性:有效期// 特有方法:检查是否过期public boolean isExpired() {// 实现过期检查逻辑return false;}
}

应用价值

  (1) 父类 Product 定义了所有商品的共性,子类无需重复编写 nameprice 等属性       和 calculateTotal 方法。

  (2)子类专注于自己的特有逻辑(如 PhysicalProduct 的运费计算),代码更简洁。

(2) 实现 “多态”,简化代码逻辑

继承允许子类对象被当作父类对象使用,从而可以用统一的方式处理不同子类的实例,减少代码分支。

示例
在支付系统中,有多种支付方式(微信支付、支付宝支付),它们都需要 “发起支付” 和 “查询支付结果” 的功能,但实现细节不同。

// 父类:定义支付的通用接口
public abstract class Payment {// 抽象方法:子类必须实现具体逻辑public abstract void pay(double amount);public abstract String queryStatus(String orderId);
}// 子类1:微信支付
public class WechatPayment extends Payment {@Overridepublic void pay(double amount) {System.out.println("微信支付:" + amount + "元");// 微信支付的具体实现(调用微信接口等)}@Overridepublic String queryStatus(String orderId) {return "微信支付状态:已支付"; // 模拟查询结果}
}// 子类2:支付宝支付
public class AlipayPayment extends Payment {@Overridepublic void pay(double amount) {System.out.println("支付宝支付:" + amount + "元");// 支付宝支付的具体实现}@Overridepublic String queryStatus(String orderId) {return "支付宝支付状态:已支付"; // 模拟查询结果}
}

(3).使用时的多态场景

public class PaymentService {// 统一处理支付:参数为父类类型,可接收任何子类对象public void processPayment(Payment payment, double amount) {payment.pay(amount); // 调用的是子类的具体实现}
}// 测试
public class Test {public static void main(String[] args) {PaymentService service = new PaymentService();// 传入微信支付对象service.processPayment(new WechatPayment(), 100); // 传入支付宝支付对象service.processPayment(new AlipayPayment(), 200); }
}

三、多态

多态的核心思想:"同一操作作用于不同对象时,产生不同的执行结果

1.多态的实现条件

在java中,多态的实现需要满足三个条件:

(1)继承关系:子类必须继承父类(或实现接口);

(2)方法重写:子类重写(@Override)父类的方法;

(3)父类引用指向子类对象:如Parent p = new Child();

2.多态的核心目的:

(1).简化代码逻辑:用统一的方式处理不同类型的对象,减少分支判断(if-else/switch);

(2)提升扩展性:新增子类时,无需修改现有的代码,只需新增实现(符合“开闭原则”);

(3)解耦:调用者只需关注父类接口,无需知道具体子类的实现细节。

3.在项目的应用场景

(1). 统一接口,不同实现(以支付系统为例)

在支付场景中,无论用户选择微信、支付宝还是银联支付,系统的核心流程都是 “发起支付”,但不同支付方式的底层实现不同。

// 1. 定义父接口(或抽象类):统一支付行为
public interface Payment {void pay(double amount); // 抽象方法:支付
}// 2. 子类实现:不同支付方式
public class WechatPayment implements Payment {@Overridepublic void pay(double amount) {System.out.println("微信支付:" + amount + "元(调用微信接口)");}
}public class AlipayPayment implements Payment {@Overridepublic void pay(double amount) {System.out.println("支付宝支付:" + amount + "元(调用支付宝接口)");}
}// 3. 调用者:依赖父接口,不关心具体实现
public class OrderService {// 统一支付入口:参数为Payment接口,可接收任何实现类public void processPayment(Payment payment, double amount) {payment.pay(amount); // 多态:实际执行子类的pay方法}
}// 测试
public class Test {public static void main(String[] args) {OrderService service = new OrderService();// 父接口引用指向不同子类对象Payment wechat = new WechatPayment();Payment alipay = new AlipayPayment();// 调用同一方法,执行不同实现service.processPayment(wechat, 100); // 微信支付:100元service.processPayment(alipay, 200); // 支付宝支付:200元}
}
(2)集合框架中的多态(Java标准库应用)

Java集合框架大量使用多态,比如List接口有ArrayList 、LinkedList等实现类:

// 父接口引用指向子类对象
List<String> list1 = new ArrayList<>(); 
List<String> list2 = new LinkedList<>();// 调用同一方法(add),执行不同实现
list1.add("a"); // ArrayList的add(数组扩容逻辑)
list2.add("b"); // LinkedList的add(链表节点插入逻辑)
(3)框架中的多态(以SpringMVC为例)
在SpringMVC中,Controller处理请求的方式不同,但框架通过多态统一调度:
// 父类/接口:Spring定义的处理器接口
public interface HandlerAdapter {boolean supports(Object handler); // 判断是否支持该处理器ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}// 子类实现:不同类型的处理器适配器
public class SimpleControllerHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return handler instanceof Controller; // 支持传统Controller}@Overridepublic ModelAndView handle(...) {// 处理传统Controller的请求}
}public class RequestMappingHandlerAdapter implements HandlerAdapter {@Overridepublic boolean supports(Object handler) {return handler instanceof HandlerMethod; // 支持@Controller注解的处理器}@Overridepublic ModelAndView handle(...) {// 处理注解式Controller的请求}
}
(4)策略模式(多态的经典设计模式)

策略模式是多态的典型应用,用于封装一组可替换的算法。例如,电商系统的折扣策略(新用户折扣、会员折扣、节日折扣):

// 1. 策略接口(父类)
public interface DiscountStrategy {double calculateDiscount(double price); // 计算折扣后价格
}// 2. 具体策略(子类)
public class NewUserDiscount implements DiscountStrategy {@Overridepublic double calculateDiscount(double price) {return price * 0.8; // 新用户8折}
}public class MemberDiscount implements DiscountStrategy {@Overridepublic double calculateDiscount(double price) {return price * 0.7; // 会员7折}
}// 3. 使用策略的上下文类
public class OrderCalculator {private DiscountStrategy strategy;// 动态设置策略(多态:接收任何策略实现)public void setStrategy(DiscountStrategy strategy) {this.strategy = strategy;}public double calculateFinalPrice(double price) {return strategy.calculateDiscount(price); // 执行当前策略}
}// 测试
public class Test {public static void main(String[] args) {OrderCalculator calculator = new OrderCalculator();// 动态切换策略calculator.setStrategy(new NewUserDiscount());System.out.println(calculator.calculateFinalPrice(100)); // 80.0calculator.setStrategy(new MemberDiscount());System.out.println(calculator.calculateFinalPrice(100)); // 70.0}
}

(5)多态的注意事项

  1. 编译时类型与运行时类型:父类引用的编译时类型是父类,运行时类型是子类(如 Payment p = new WechatPayment() 中,编译时 p 是 Payment 类型,运行时是 WechatPayment 类型);
  2. 方法调用规则:多态仅针对 “实例方法”,静态方法、字段不支持多态(调用时取决于编译时类型);
  3. 向上转型与向下转型:
    • 向上转型(自动):Parent p = new Child();(安全,多态的基础);
    • 向下转型(强制):Child c = (Child)p;(需用 instanceof 检查,否则可能抛 ClassCastException)。

http://www.lryc.cn/news/624933.html

相关文章:

  • 机器人技术核心模块与前沿趋势总结
  • TikTok墨西哥POP店今日正式开放!0佣金+流量扶持+5店开放
  • PG靶机 - Bratarina
  • C# NX二次开发:字符串控件StringBlock讲解
  • Pandas 中常用的统计计算、排序、分组聚合
  • plantsimulation知识点25.8.18-从一个RGV到另一台RGV,工件长度和宽度方向互换
  • 【牛客刷题】计算1到n最低位1代表的数字之和
  • Layui COP证书管理系统
  • 《Image Classification with Classic and Deep Learning Techniques》复现
  • 吴恩达 Machine Learning(Class 1)
  • cross-env 与 @nestjs/config 的对比分析
  • 小杰机械视觉(one day)——基础阶段结束,进入机械学习阶段。
  • leetcode43. 字符串相乘
  • TEST_
  • 10CL016YF484C8G Altera FPGA Cyclone
  • 视觉语言导航(8)——任务驱动的架构增强 3.3
  • 矿物分类案例(二)数据填充后使用6种模型训练
  • Android中flavor的使用
  • PostgreSQL中的json_agg()
  • 初始向量数据库之Milvus
  • milvus如何存储特殊类型的数据
  • Milvus向量数据库安装步骤
  • 大厂 | 华为半导体业务部2026届秋招启动
  • 【大模型】RAG
  • 基于nvm安装管理多个node.js版本切换使用(附上详细安装使用图文教程+nvm命令大全)
  • ANSI终端色彩控制知识散播(I):语法封装(Python)——《彩色终端》诗评
  • 楼宇自控系统深化设计需关注哪些核心要点?技术与应用解析
  • 第一阶段C#-14:委托,事件
  • ReactNative开发实战——React Native开发环境配置指南
  • 机器翻译论文阅读方法:顶会(ACL、EMNLP)论文解析技巧