面向对象设计-封装

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

封装的步骤:

  • 修改属性的可见性(使用 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+属性名,记住方法的命名规则------首字母小写,如果方法名由多个单词组成,除了第一个单词,其它每个单词的首字母都要大写。

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

相关推荐
Vitalia2 小时前
从零开始学Rust:枚举(enum)与模式匹配核心机制
开发语言·后端·rust
飞飞翼3 小时前
python-flask
后端·python·flask
草捏子4 小时前
最终一致性避坑指南:小白也能看懂的分布式系统生存法则
后端
一个public的class5 小时前
什么是 Java 泛型
java·开发语言·后端
头孢头孢6 小时前
k8s常用总结
运维·后端·k8s
TheITSea6 小时前
后端开发 SpringBoot 工程模板
spring boot·后端
Asthenia04126 小时前
编译原理中的词法分析器:从文本到符号的桥梁
后端
Asthenia04126 小时前
用RocketMQ和MyBatis实现下单-减库存-扣钱的事务一致性
后端
Pasregret6 小时前
04-深入解析 Spring 事务管理原理及源码
java·数据库·后端·spring·oracle
Micro麦可乐6 小时前
最新Spring Security实战教程(七)方法级安全控制@PreAuthorize注解的灵活运用
java·spring boot·后端·spring·intellij-idea·spring security