面向对象设计-封装

封装,就是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

封装的步骤:

  • 修改属性的可见性(使用 private 修饰)
  • 创建 getter/setter 方法,用于属性的读写,一般此方法是用 public 修饰。
  • 必要时可以在 getter/setter 方法添加逻辑控制语句,保证属性的合法性。

前面我们已经给大家介绍了类和对象,当时我们没有介绍对象的特征封装。那到底什么是封装呢?它的好处又是什么呢?接下来让我一一为你揭秘。

我们都知道每一个人都有自己的小秘密,不想被别人所熟知。同样在 Java 世界中的对象也有自己的隐私,对象的隐私就是对象内部的实现细节。那如何保护这些隐私呢,这就需要我们的封装来实现了 😊。

  1. 封装的概念。 封装就是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

  2. 封装的目的是简化编程和增强安全性。

    • 简化编程是指,封装可以让使用者不必了解具体类的内部实现细节,而只是要通过提供给外部访问的方法来访问类中的属性和方法。例如 Java API 中的 Arrays.sort()方法,该方法可以用于给数组进行排序操作,开发者只需要将待排序的数组名放到 Arrays.sort()方法的参数中,该方法就会自动的将数组排好序。可见,开发者根本不需要了解 Arrays.sort()方法的底层逻辑,只需要简单的将数组名传递给方法即可实现排序。
    • 增强安全性是指,封装可以使某个属性只能被当前类使用,从而避免被其他类或对象进行误操作。例如在 Student.java 的程序中,StudentstuAge 属性是 public 的形式体现的,但这样做实际存在着安全隐患:TestStudent 类(或在访问修饰符可见范围内的其他类)完全可以随意的对 stuAge 进行修改,如以下程序。
arduino 复制代码
/**
 * 定义一个学生类
 * @author lanqiao
 */
public class Student {
    public String stuName;     // 学生姓名
    public int stuAge;      // 学生年龄
    ...
}
ini 复制代码
/**
 * 定义一个学生测试类
 * @author lanqiao
 */
public class TestStudent {
    public static void main(String[] args) {
        Student xiaolan = new Student();
        xiaolan.stuName = "小蓝";
        xiaolan.stuAge = -10;
        ...
    }
}

如上,给 stuAge 赋了一个不符合逻辑的值,但语法是却正确的。因此这种做法,实际会给程序造成一定程度上的安全问题。那么此时我们就可以使用封装Student.java 内部的信息不能随便被外部访问,要想访问可以通过供外部访问的方法去访问。

封装好处:a. 只能通过规定的方法访问数据; b.隐藏类的实例细节,方便修改和实现。

  1. 封装的实现步骤。

根据上图中的步骤,我们来修改 Student.java 程序中的代码,然后在 TestStudent 类进行测试:

  • 使用 private 修饰 Student.java 文件中的成员变量,给每个成员变量添加一个 getter/setter 方法并且给变量添加合适的逻辑控制语句:
typescript 复制代码
/**
 * 定义一个学生类
 * @author lanqiao
 */
public class Student {
    private String stuName;  //学生姓名
    private int stuAge;      //学生年龄

    // 给属性提供 getter/setter 方法
    // 获取stuName的值
    public String getStuName(){
        return stuName;
    }

    // 给 stuName 赋值
    public void setStuName(String name){
        stuName = name;
    }

    // 获取 stuAge 的值
    public int getStuAge(){
        return stuAge;
    }

    // 给 stuAge 的赋一个合法的值
    public void setStuAge(int age){
        //如果年龄在合理范围内,则正常赋值
        if( age >0 && age <120){
            stuAge = age;
        }else{ //如果对年龄的赋值不合理,则设置为默认值0
            stuAge = 0 ;
        }
    }
}
  • 修改 TestStudent.java 文件中的代码:
arduino 复制代码
/**
 * 定义一个学生测试类
 * @author lanqiao
 */
public class TestStudent {
    public static void main(String[] args) {
        Student xiaolan = new Student();
        /* 如果将stuAge赋值负数,setStuAge()就会将stuAge设置为默认值0,防止出现安全问题。
        xiaolan.setStuAge(-10); */
        xiaolan.setStuAge(22); // 给年龄赋值
        xiaolan.setStuName("小蓝");
        int age = xiaolan.getStuAge() ;
        String name = xiaolan.getStuName();

        System.out.println("姓名:" + name + "\t年龄:" + age);
    }
}
  • 编译运行程序,最终结果如下图所示:

    javac TestStudent.java
    java TestStudent

⭐ 上面我们已经使用面向对象的特征封装改造好了程序,接下来我们一起来分析总结一下:

  • 使用 private 修饰符修饰的成员信息,外部不能直接访问(包括成员变量和成员方法)。

  • 使用 private 可以保证安全,但是如果其他类想需要这些信息,那该怎么办呢?有没有一种办法,既能让其他类可以访问类中使用private 修饰的成员信息,又能保证获取到的信息合法并安全呢?有,那就是给该属性提供两个 public 修饰的、保证属性安全的访问方法(setter 方法和 getter 方法),即:

    a. 用 private 禁止其他类直接访问属性;

    b. 给 private 修饰的属性新增两个 public 修饰的 settergetter 方法,供其他类安全的访问。

  • setter 方法用于给属性赋值,而 getter 访问用于获取属性的值。正常情况下,setter 方法的名字通常是 set+属性名getter 方法的名字通常是 get+属性名,记住方法的命名规则------首字母小写,如果方法名由多个单词组成,除了第一个单词,其它每个单词的首字母都要大写。

以上就是对象的第一个特征:封装,不难吧 😊。

相关推荐
cg331 小时前
cc-connect,十分钟帮你把 claude code 连接到微信,飞书,钉钉等等平台
后端·openai
用户1427868669321 小时前
Java多态的底层真相:JVM到底怎么知道该调哪个方法?(面试高频)
后端
初次攀爬者1 小时前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
摸鱼的春哥1 小时前
惊!黑客靠AI把墨西哥政府打穿了,海量数据被黑
前端·javascript·后端
考虑考虑2 小时前
JDK25模块导入声明
java·后端·java ee
想用offer打牌3 小时前
高并发下如何保证接口的幂等性
后端·面试·状态机
爱勇宝4 小时前
2026一人公司生存指南:用AI大模型,90天跑出你的第一条现金流
前端·后端·架构
golang学习记4 小时前
Go 并发编程:原子操作(Atomics)完全指南
后端
哈里谢顿5 小时前
`127.0.0.1` 和 `0.0.0.0` 有何区别?通过验证 demo来展示
后端
树獭叔叔5 小时前
08-大模型后训练的指令微调SFT:LoRA让大模型微调成本降低99%
后端·aigc·openai