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

Java 封装

Java 封装

在各个面向对象语言里,面向对象有三大特征,即封装、继承和多态。下面我们将详细探讨 Java 中的封装,包括其概念、特点、为何需要封装、实现方式,最后通过一个 NBA 球员类的案例来加深理解。

1. 概念和特点

封装是将对象的状态(属性)和行为(操作数据的方法)捆绑在一起,并对外界隐藏其内部实现细节的过程。类的基本作用就是封装代码,它把类的一些特征和行为隐藏在类内部,不允许类外部直接访问,而是通过类提供的方法来实现对隐藏信息的操作和访问,相当于设置了一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

封装有两个显著特点:

  • 只能通过规定的方法访问数据;
  • 隐藏类的实例细节,方便修改和实现。

在日常生活中,封装的例子随处可见,例如智能手机。我们无需关心其内部复杂的逻辑电路设计,只需通过手机的屏幕、按键、充电口、耳机接口等外部接口就能对手机进行操作和使用。复杂的逻辑电路以及模块被封装在手机内部,而这些必要接口的留出,让我们更简便地使用手机,同时也保护了手机的内部细节。

2. 为什么需要封装

封装具有诸多优点:

  • 提高内聚性:有利于提高类的内聚性,适当的封装能让代码更易于理解和维护。类的内部数据操作细节自己完成,不允许外部干涉。
  • 降低耦合度:良好的封装可降低代码的耦合度,仅暴露少量的方法给外部使用,尽量方便外部调用。
  • 增强安全性:一些关键属性只允许类内部访问和修改,通过访问修饰符限制对对象内部数据的直接访问,还能实施更精细的控制逻辑,如数据验证,从而确保数据的完整性和一致性,增强类的安全性。
  • 简化接口:隐藏实现细节,为调用方提供易于理解的接口,用户只需知道对象能做什么(通过其提供的方法),而无需了解具体实现方式,符合黑盒设计原则。
  • 方便修改:当需求发生变动时,只需修改封装的代码,而不用到处修改调用处的代码,提高了软件的可维护性和扩展性。
3. 实现封装

在 Java 语言中,实现封装需要以下 3 个步骤:

  • 修改属性可见性:将属性的可见性修改为 private,这表明该属性只能在当前类内被访问,出了这个类就无法直接访问。
  • 创建公开的 getter 和 setter 方法:通常以 get + 属性名 的方式命名 getter 方法,用于返回对应的私有属性;以 set + 属性名 的方式命名 setter 方法,用于给对应属性进行赋值。这样在类的外部就可以通过调用这些方法对属性进行操作。
  • 进行属性合法性判断:在 getter 和 setter 方法中,对属性的合法性进行判断。例如,对于年龄属性,可判断其是否为正值。

下面通过一个 NBA 球员类 NBAPlayer 来展示封装的实现:

public class NBAPlayer {
    // 姓名
    private String name;
    // 年龄
    private int age;

    // 无参构造方法
    public NBAPlayer() {

    }

    // 单参构造方法
    public NBAPlayer(int age) {
        this.setAge(age);
    }

    // 全参构造方法
    public NBAPlayer(String name, int age) {
        this.setName(name);
        this.setAge(age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 判断参数 age 的合法性
        if (age < 0) {
            this.age = 0;
        } else {
            this.age = age;
        }
    }

    public static void main(String[] args) {
        NBAPlayer james = new NBAPlayer();
        // 对属性赋值:
        james.setName("詹姆斯");
        james.setAge(35);
        // 打印 james 实例属性
        System.out.println("姓名:" + james.getName());
        System.out.println("年龄:" + james.getAge());
        System.out.println("-------------");
        // 实例化一个新的对象
        NBAPlayer jordan = new NBAPlayer("乔丹", 60);
        // 打印 jordan 对象实例属性
        System.out.println("姓名:" + jordan.getName());
        System.out.println("年龄:" + jordan.getAge());
    }
}

在上述代码中,最初定义的 NBAPlayer 类没有进行封装,外部可以直接对属性进行赋值,可能会出现不合理的数据,如年龄为负数。通过封装,将属性 nameage 设为 private,并提供了相应的 getter 和 setter 方法,同时在 setAge 方法中对年龄的合法性进行了判断,避免了不合理数据的输入。如果在类外部有很多地方都会操作属性值,当属性值读写逻辑发生改变时,只需修改类内部的逻辑即可。另外,在有参构造方法中,对属性赋值时直接调用其 setter 方法,无需再写重复的逻辑判断,提高了代码复用性。

4. 小结

封装是面向对象的重要特征之一,它隐藏了对象的信息,并且留出了访问的接口。通过封装,我们可以提高代码的安全性、可维护性和复用性,使代码更加模块化和易于使用。


http://www.kler.cn/a/558184.html

相关文章:

  • 如何利用AWS算力构建高效AI场景案例:从大模型训练到部署实战
  • Element UI中messageBox怎么区分点击取消按钮关闭弹窗,和点击右上角x号以及点击遮罩层关闭按钮
  • pgAdmin4在mac m1上面简单使用(Docker)
  • [Linux]从零开始的STM32MP157 U-Boot网络命令讲解及相关配置
  • 聊聊 FocusSearch/focus_mcp_sql:Text2SQL 的新玩法
  • web安全:跨站请求伪造 (CSRF)
  • Java四大框架深度剖析:MyBatis、Spring、SpringMVC与SpringBoot
  • anaconda不显示jupyter了?
  • 小红书架构演进与关键技术解析
  • 泛微OA编写后端Rest接口
  • Go 错误处理与调试:面向对象的入门教程
  • 系统架构设计师备考策略
  • 【Java从入门到起飞】数组
  • 安卓系统远程控制电脑方法,手机远控教程,ToDesk工具
  • Deepseek存算分离安全部署手册
  • 力扣-回溯-332 重新安排行程
  • 前端八股——计算机网络+浏览器原理
  • Selenium库详解:Python实现模拟登录与反爬限制的进阶指南
  • 【含开题报告+文档+PPT+源码】基于springboot加vue 前后端分离的校园新闻审核发布管理系统
  • 国产单片机开发汽车气压表胎压计解决方案