最好的外贸网站建设,网站建设留言板怎么做,wordpress 改ip,前端网站开发实例Java面向对象编程详解
在Java编程世界中#xff0c;面向对象编程#xff08;OOP#xff09;是最核心的编程范式。无论是开发企业级应用、Android应用还是大数据处理#xff0c;掌握面向对象的思想都是成为优秀Java开发者的必经之路。
本文将深入浅出地讲解Java面向对象的四…Java面向对象编程详解在Java编程世界中面向对象编程OOP是最核心的编程范式。无论是开发企业级应用、Android应用还是大数据处理掌握面向对象的思想都是成为优秀Java开发者的必经之路。本文将深入浅出地讲解Java面向对象的四大特性封装、继承、多态、抽象结合Spring框架等生产级代码示例帮助你真正理解OOP的精髓。一、面向对象编程概述1.1 什么是面向对象面向对象编程Object-Oriented ProgrammingOOP是一种将现实世界的事物抽象为程序中对象的编程思想。核心理念万物皆对象现实世界的任何事物都可以抽象为对象对象有状态和行为状态用属性表示行为用方法表示对象之间通过消息通信方法调用就是发送消息1.2 面向对象 vs 面向过程对比项面向过程面向对象关注点解决问题的步骤解决问题的对象代码组织函数类和对象数据安全数据暴露数据封装代码复用函数复用继承、组合扩展性较差良好适用场景简单脚本复杂系统二、封装保护数据的第一道防线2.1 什么是封装封装Encapsulation是将对象的属性和方法包装在一起隐藏内部实现细节只对外暴露必要的接口。封装的三要素私有化属性使用private修饰提供公共访问方法getter和setter在方法中加入控制逻辑数据验证2.2 封装的实际应用/** * 用户实体类 - 演示封装 * 实际生产中的写法 */publicclassUser{// 私有属性privateLongid;privateStringusername;privateStringpassword;privateStringemail;privateIntegerage;privateLocalDateTimecreateTime;// 无参构造器publicUser(){this.createTimeLocalDateTime.now();}// 全参构造器publicUser(Stringusername,Stringpassword,Stringemail){this();this.usernameusername;setPassword(password);// 使用setter进行加密setEmail(email);// 使用setter进行校验}// Getter方法publicLonggetId(){returnid;}publicStringgetUsername(){returnusername;}// 密码不直接返回返回脱敏后的publicStringgetPassword(){return******;}// Setter方法 - 包含业务逻辑publicvoidsetUsername(Stringusername){if(usernamenull||username.trim().isEmpty()){thrownewIllegalArgumentException(用户名不能为空);}if(username.length()3||username.length()20){thrownewIllegalArgumentException(用户名长度必须在3-20之间);}this.usernameusername.trim();}// 密码加密存储publicvoidsetPassword(Stringpassword){if(passwordnull||password.length()6){thrownewIllegalArgumentException(密码长度不能小于6位);}// 实际生产中使用BCrypt加密this.passwordhashPassword(password);}// 邮箱格式验证publicvoidsetEmail(Stringemail){if(email!null!email.matches(^[\\w-\\.][\\w-]\\.[a-z]{2,}$)){thrownewIllegalArgumentException(邮箱格式不正确);}this.emailemail;}// 年龄范围验证publicvoidsetAge(Integerage){if(age!null(age0||age150)){thrownewIllegalArgumentException(年龄必须在0-150之间);}this.ageage;}// 私有方法 - 密码哈希privateStringhashPassword(Stringpassword){// 简化示例实际使用BCryptreturnHASHED_password.hashCode();}}2.3 Spring框架中的封装实践Spring框架大量使用封装来保护核心组件/** * 模拟Spring的BeanFactory封装思想 */publicclassSimpleBeanFactory{// 私有的Bean容器privatefinalMapString,ObjectbeanMapnewConcurrentHashMap();// 私有的Bean定义privatefinalMapString,BeanDefinitionbeanDefinitionMapnewHashMap();// 对外暴露的获取Bean方法publicObjectgetBean(StringbeanName){// 先从缓存获取ObjectbeanbeanMap.get(beanName);if(bean!null){returnbean;}// 创建Bean简化版BeanDefinitiondefinitionbeanDefinitionMap.get(beanName);if(definitionnull){thrownewRuntimeException(Bean not found: beanName);}beancreateBean(definition);beanMap.put(beanName,bean);returnbean;}// 私有的创建Bean方法privateObjectcreateBean(BeanDefinitiondefinition){// 内部实现细节对外隐藏try{returndefinition.getBeanClass().newInstance();}catch(Exceptione){thrownewRuntimeException(创建Bean失败,e);}}}三、继承代码复用的利器3.1 什么是继承继承Inheritance是子类获得父类的属性和方法的机制是实现代码复用的重要手段。继承的特点Java只支持单继承一个类只能有一个父类支持多层继承A继承BB继承C所有类都隐式继承Object类使用extends关键字3.2 继承的实际应用/** * 基础实体类 - 所有实体的父类 * 生产级代码通常都有这样的基类 */publicabstractclassBaseEntity{protectedLongid;protectedLocalDateTimecreateTime;protectedLocalDateTimeupdateTime;protectedStringcreateBy;protectedStringupdateBy;protectedBooleandeletedfalse;// 创建时自动填充publicvoidonCreate(){this.createTimeLocalDateTime.now();this.updateTimethis.createTime;}// 更新时自动填充publicvoidonUpdate(){this.updateTimeLocalDateTime.now();}// Getter和Setter省略...publicLonggetId(){returnid;}publicvoidsetId(Longid){this.idid;}}/** * 用户实体 - 继承基础实体 */publicclassUserEntityextendsBaseEntity{privateStringusername;privateStringpassword;privateStringemail;privateIntegerstatus;// 子类特有的方法publicbooleanisActive(){returnstatus!nullstatus1;}// Getter和Setter...}/** * 订单实体 - 继承基础实体 */publicclassOrderEntityextendsBaseEntity{privateStringorderNo;privateLonguserId;privateBigDecimaltotalAmount;privateIntegerstatus;// 子类特有的方法publicbooleancanCancel(){returnstatus!nullstatus0;// 待支付状态可取消}}3.3 MyBatis-Plus中的继承应用/** * 通用Service接口 - MyBatis-Plus风格 */publicinterfaceIBaseServiceT{TgetById(Longid);ListTlist();booleansave(Tentity);booleanupdateById(Tentity);booleanremoveById(Longid);}/** * 通用Service实现 */publicabstractclassBaseServiceImplMextendsBaseMapperT,TimplementsIBaseServiceT{AutowiredprotectedMbaseMapper;OverridepublicTgetById(Longid){returnbaseMapper.selectById(id);}OverridepublicListTlist(){returnbaseMapper.selectList(null);}Overridepublicbooleansave(Tentity){returnbaseMapper.insert(entity)0;}OverridepublicbooleanupdateById(Tentity){returnbaseMapper.updateById(entity)0;}OverridepublicbooleanremoveById(Longid){returnbaseMapper.deleteById(id)0;}}/** * 用户Service - 继承通用实现 */ServicepublicclassUserServiceImplextendsBaseServiceImplUserMapper,UserEntityimplementsIUserService{// 只需要实现特有的业务方法publicUserEntityfindByUsername(Stringusername){returnbaseMapper.selectByUsername(username);}}四、多态灵活性的源泉4.1 什么是多态多态Polymorphism是指同一个行为具有多种不同表现形式的能力。多态的三个必要条件继承或实现接口方法重写父类引用指向子类对象4.2 多态的实际应用/** * 支付接口 - 定义支付行为 */publicinterfacePaymentService{/** * 执行支付 * param orderId 订单ID * param amount 支付金额 * return 支付结果 */PaymentResultpay(StringorderId,BigDecimalamount);/** * 查询支付状态 */PaymentStatusqueryStatus(StringorderId);/** * 获取支付方式名称 */StringgetPaymentType();}/** * 支付宝支付实现 */Service(alipayService)publicclassAlipayServiceImplimplementsPaymentService{OverridepublicPaymentResultpay(StringorderId,BigDecimalamount){System.out.println(调用支付宝SDK进行支付...);// 调用支付宝API// AlipayClient.execute(request);returnPaymentResult.success(支付宝支付成功);}OverridepublicPaymentStatusqueryStatus(StringorderId){System.out.println(查询支付宝订单状态...);returnPaymentStatus.SUCCESS;}OverridepublicStringgetPaymentType(){returnALIPAY;}}/** * 微信支付实现 */Service(wechatPayService)publicclassWechatPayServiceImplimplementsPaymentService{OverridepublicPaymentResultpay(StringorderId,BigDecimalamount){System.out.println(调用微信支付SDK...);// 调用微信支付APIreturnPaymentResult.success(微信支付成功);}OverridepublicPaymentStatusqueryStatus(StringorderId){System.out.println(查询微信支付订单状态...);returnPaymentStatus.SUCCESS;}OverridepublicStringgetPaymentType(){returnWECHAT;}}/** * 银联支付实现 */Service(unionPayService)publicclassUnionPayServiceImplimplementsPaymentService{OverridepublicPaymentResultpay(StringorderId,BigDecimalamount){System.out.println(调用银联支付接口...);returnPaymentResult.success(银联支付成功);}OverridepublicPaymentStatusqueryStatus(StringorderId){returnPaymentStatus.SUCCESS;}OverridepublicStringgetPaymentType(){returnUNION_PAY;}}4.3 策略模式 多态的生产实践/** * 支付策略上下文 - 利用多态实现策略模式 */ComponentpublicclassPaymentContext{privatefinalMapString,PaymentServicepaymentServiceMap;// Spring自动注入所有PaymentService实现AutowiredpublicPaymentContext(ListPaymentServicepaymentServices){paymentServiceMappaymentServices.stream().collect(Collectors.toMap(PaymentService::getPaymentType,Function.identity()));}/** * 执行支付 - 多态的典型应用 */publicPaymentResultexecutePayment(StringpayType,StringorderId,BigDecimalamount){// 根据支付类型获取对应的实现PaymentServicepaymentServicepaymentServiceMap.get(payType);if(paymentServicenull){thrownewIllegalArgumentException(不支持的支付方式: payType);}// 多态调用 - 同一个方法不同的实现returnpaymentService.pay(orderId,amount);}}/** * 订单服务 - 使用支付上下文 */ServicepublicclassOrderService{AutowiredprivatePaymentContextpaymentContext;publicvoidprocessPayment(Orderorder){// 根据用户选择的支付方式调用不同的支付实现PaymentResultresultpaymentContext.executePayment(order.getPayType(),order.getOrderNo(),order.getAmount());if(result.isSuccess()){order.setStatus(OrderStatus.PAID);}}}五、抽象设计的艺术5.1 什么是抽象抽象Abstraction是将对象的共同特征提取出来形成类或接口的过程。Java中的抽象方式抽象类abstract class可以有抽象方法和具体方法接口interfaceJava 8后可以有默认方法5.2 抽象类的应用/** * 抽象模板 - 数据导出器 * 使用模板方法模式 */publicabstractclassAbstractDataExporterT{/** * 导出数据 - 模板方法final防止子类修改流程 */publicfinalvoidexport(ListTdataList,StringfilePath){// 1. 数据校验validateData(dataList);// 2. 数据预处理ListTprocessedDatapreProcess(dataList);// 3. 执行导出抽象方法子类实现doExport(processedData,filePath);// 4. 后置处理postProcess(filePath);System.out.println(导出完成: filePath);}// 钩子方法 - 子类可选重写protectedvoidvalidateData(ListTdataList){if(dataListnull||dataList.isEmpty()){thrownewIllegalArgumentException(导出数据不能为空);}}// 钩子方法 - 默认不处理protectedListTpreProcess(ListTdataList){returndataList;}// 抽象方法 - 子类必须实现protectedabstractvoiddoExport(ListTdataList,StringfilePath);// 钩子方法 - 默认不处理protectedvoidpostProcess(StringfilePath){// 子类可重写}}/** * Excel导出器 */ComponentpublicclassExcelExporterextendsAbstractDataExporterMapString,Object{OverrideprotectedvoiddoExport(ListMapString,ObjectdataList,StringfilePath){System.out.println(使用POI导出Excel文件...);// 实际使用Apache POI或EasyExcel}OverrideprotectedvoidpostProcess(StringfilePath){System.out.println(Excel导出后处理添加水印);}}/** * CSV导出器 */ComponentpublicclassCsvExporterextendsAbstractDataExporterMapString,Object{OverrideprotectedvoiddoExport(ListMapString,ObjectdataList,StringfilePath){System.out.println(导出CSV文件...);// 使用OpenCSV或手动拼接}}/** * PDF导出器 */ComponentpublicclassPdfExporterextendsAbstractDataExporterMapString,Object{OverrideprotectedListMapString,ObjectpreProcess(ListMapString,ObjectdataList){System.out.println(PDF预处理格式化数据);returndataList;}OverrideprotectedvoiddoExport(ListMapString,ObjectdataList,StringfilePath){System.out.println(使用iText导出PDF文件...);}}5.3 接口的应用/** * 缓存接口 - 定义缓存行为 */publicinterfaceCacheService{voidset(Stringkey,Objectvalue);voidset(Stringkey,Objectvalue,longtimeout,TimeUnitunit);TTget(Stringkey,ClassTclazz);booleandelete(Stringkey);booleanhasKey(Stringkey);// Java 8 默认方法defaultvoidsetWithDefaultExpire(Stringkey,Objectvalue){set(key,value,30,TimeUnit.MINUTES);}}/** * Redis缓存实现 */ServicePrimarypublicclassRedisCacheServiceimplementsCacheService{AutowiredprivateRedisTemplateString,ObjectredisTemplate;Overridepublicvoidset(Stringkey,Objectvalue){redisTemplate.opsForValue().set(key,value);}Overridepublicvoidset(Stringkey,Objectvalue,longtimeout,TimeUnitunit){redisTemplate.opsForValue().set(key,value,timeout,unit);}OverridepublicTTget(Stringkey,ClassTclazz){ObjectvalueredisTemplate.opsForValue().get(key);returnclazz.cast(value);}Overridepublicbooleandelete(Stringkey){returnBoolean.TRUE.equals(redisTemplate.delete(key));}OverridepublicbooleanhasKey(Stringkey){returnBoolean.TRUE.equals(redisTemplate.hasKey(key));}}/** * 本地缓存实现用于开发环境 */ServicepublicclassLocalCacheServiceimplementsCacheService{privatefinalMapString,ObjectcachenewConcurrentHashMap();Overridepublicvoidset(Stringkey,Objectvalue){cache.put(key,value);}Overridepublicvoidset(Stringkey,Objectvalue,longtimeout,TimeUnitunit){cache.put(key,value);// 简化版实际需要处理过期}OverridepublicTTget(Stringkey,ClassTclazz){returnclazz.cast(cache.get(key));}Overridepublicbooleandelete(Stringkey){returncache.remove(key)!null;}OverridepublicbooleanhasKey(Stringkey){returncache.containsKey(key);}}六、面向对象设计原则6.1 SOLID原则原则说明示例S- 单一职责一个类只负责一件事UserService只处理用户业务O- 开闭原则对扩展开放对修改关闭通过接口添加新支付方式L- 里氏替换子类可以替换父类List list new ArrayList()I- 接口隔离接口要小而专一拆分大接口为多个小接口D- 依赖倒置依赖抽象而非具体依赖PaymentService接口6.2 组合优于继承/** * 使用组合而非继承 */publicclassOrderService{// 组合持有其他对象的引用privatefinalUserServiceuserService;privatefinalPaymentServicepaymentService;privatefinalInventoryServiceinventoryService;privatefinalNotificationServicenotificationService;publicOrderService(UserServiceuserService,PaymentServicepaymentService,InventoryServiceinventoryService,NotificationServicenotificationService){this.userServiceuserService;this.paymentServicepaymentService;this.inventoryServiceinventoryService;this.notificationServicenotificationService;}publicOrdercreateOrder(OrderRequestrequest){// 1. 校验用户UseruseruserService.getById(request.getUserId());// 2. 校验库存inventoryService.checkStock(request.getItems());// 3. 创建订单OrderorderbuildOrder(request,user);// 4. 扣减库存inventoryService.deductStock(request.getItems());// 5. 发送通知notificationService.sendOrderCreatedNotification(order);returnorder;}}七、总结核心要点封装保护数据隐藏实现对外提供接口继承代码复用建立类层次结构多态同一接口不同实现提高灵活性抽象提取共性定义规范降低耦合实践建议优先使用组合而非继承面向接口编程遵循SOLID原则保持类的职责单一合理使用设计模式