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

后端Java开发:第十二天

第十二天:封装 - 理解与应用

欢迎来到今天的学习内容!今天,我们将一起深入探讨 Java 中的 封装(Encapsulation)。封装是面向对象编程的四大基本特性之一,它的核心思想是把对象的状态(属性)和行为(方法)绑定在一起,并隐藏对象的实现细节,只暴露必要的接口给外部。这使得对象的内部状态不会被随意修改,同时保证了数据的安全性和代码的可维护性。

1. 什么是封装?

封装是一种将对象的状态和行为隐藏在对象内部的技术,外部无法直接访问对象的内部数据,只能通过 公开的接口(通常是方法)来操作数据。这种做法能够有效避免外部代码错误地修改对象的内部状态,并提供了一种更高层次的代码抽象。

封装主要包括以下几个方面:

  • 属性私有化(private):将类的属性声明为私有,禁止外部直接访问。
  • 提供公共的访问方法(getters 和 setters):通过方法(getters 和 setters)来访问和修改属性。
  • 实现类的接口:通过公开的方法来提供给外部使用,而不直接暴露内部的实现细节。

2. 封装的好处

封装有很多好处,以下是几项关键优势:

  • 数据保护:通过将数据设为私有,可以防止外部直接修改对象的属性,确保数据的安全性。
  • 提高可维护性:如果需要更改属性的实现方式,只需要修改类内部的代码,而不需要修改外部的调用代码。
  • 提高代码的复用性:通过提供接口方法,外部可以在不修改类的内部实现的情况下使用类的功能。
  • 简化复杂性:通过封装内部实现,外部只需要关心接口的使用,而无需了解类的内部细节。

3. 如何实现封装?

在 Java 中实现封装通常通过以下步骤:

步骤 1:将类的属性设为私有(private)

私有化类的属性,避免外部直接访问或修改这些属性。

步骤 2:为每个属性提供公共的访问方法(getters 和 setters)

通过 getset 方法允许外部读取和修改属性的值。get 方法用于获取属性的值,set 方法用于设置属性的值

步骤 3:类的其他方法

提供其他功能性的方法,这些方法不直接暴露内部实现,但可以通过接口与外部交互。

代码示例

public class Person {
    // 1. 将属性设为私有
    private String name;
    private int age;

    // 2. 提供公共的 getter 和 setter 方法
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 设置年龄时,可以添加验证逻辑
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("Age must be greater than 0");
        }
    }

    // 3. 提供其他公共方法
    public void introduce() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }

    public static void main(String[] args) {
        Person person = new Person();
        person.setName("Alice");
        person.setAge(30);
        person.introduce();
    }
}

输出

Hello, my name is Alice and I am 30 years old.

4. 封装的实例分析

实例 1:银行账户类 - 提供存取款操作

我们用封装来设计一个银行账户类,这个类将拥有账户余额(balance)这个私有属性,并提供存款和取款的方法,同时加入一些验证逻辑,确保账户余额不能为负。

public class BankAccount {
    // 私有属性
    private double balance;

    // 公共的 getter 方法
    public double getBalance() {
        return balance;
    }

    // 公共的存款方法
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: " + amount);
        } else {
            System.out.println("Deposit amount must be greater than 0");
        }
    }

    // 公共的取款方法
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrew: " + amount);
        } else {
            System.out.println("Insufficient balance or invalid amount");
        }
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        account.deposit(1000);
        account.withdraw(500);
        account.withdraw(600);  // 失败,余额不足
        System.out.println("Current Balance: " + account.getBalance());
    }
}

输出

Deposited: 1000.0
Withdrew: 500.0
Insufficient balance or invalid amount
Current Balance: 500.0
实例 2:学生类 - 姓名和成绩的封装

在此示例中,封装用于保护学生的成绩数据,只允许通过 getset 方法进行访问,同时加入了成绩验证的逻辑,确保成绩不超过 100 分。

public class Student {
    private String name;
    private double grade;

    // 设置姓名
    public void setName(String name) {
        this.name = name;
    }

    // 获取姓名
    public String getName() {
        return name;
    }

    // 设置成绩
    public void setGrade(double grade) {
        if (grade >= 0 && grade <= 100) {
            this.grade = grade;
        } else {
            System.out.println("Grade must be between 0 and 100.");
        }
    }

    // 获取成绩
    public double getGrade() {
        return grade;
    }

    // 打印学生信息
    public void printInfo() {
        System.out.println("Student: " + name + ", Grade: " + grade);
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.setName("Bob");
        student.setGrade(85);
        student.printInfo();
    }
}

输出

Student: Bob, Grade: 85.0

5. 常见的封装误区

误区 1:不使用 gettersetter 方法

有些开发者会直接将类的属性设为公共的,这样虽然方便访问,但却会暴露内部实现,破坏封装的原则。

public class WrongPerson {
    public String name;
    public int age;

    public static void main(String[] args) {
        WrongPerson person = new WrongPerson();
        person.name = "Alice";  // 直接修改属性
        person.age = 30;
        System.out.println("Name: " + person.name + ", Age: " + person.age);
    }
}

建议:将类的属性设为私有,提供 getset 方法,增强数据的保护性。

误区 2:忽视封装的其他方面

封装不仅仅是将属性设为私有,还应注意:

  • 封装业务逻辑:确保类的行为逻辑都封装在类内部,外部只暴露必要的接口。
  • 数据验证:在 set 方法中加入数据验证逻辑,确保数据的合理性。

6. 总结

通过今天的学习,我们了解了 封装(Encapsulation) 的基本概念和应用。封装是面向对象编程中的一个重要特性,它帮助我们隐藏对象的实现细节,保护数据安全,并提高代码的可维护性。通过将属性私有化,并提供公共的 getset 方法,我们可以更好地控制数据的访问和修改。

封装让我们能够确保代码的安全性、可靠性和简洁性。在实际开发中,封装不仅仅是访问控制,它还包含了对数据的验证、业务逻辑的封装等多个方面。

明天我们将继续探讨面向对象编程中的另一个重要特性——继承。敬请期待!


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

相关文章:

  • 攻防世界 ics-07
  • Spring Boot教程之四十九:Spring Boot – MongoRepository 示例
  • DuckDB:PRAGMA语句动态配置数据库行为
  • WandB使用笔记
  • ASP.NET Core 实现微服务 - Elastic APM
  • 【AI-21】深度学习框架中的神经网络
  • AI大模型-提示工程学习笔记4
  • 【实用技能】如何使用 .NET C# 中的 Azure Key Vault 中的 PFX 证书对 PDF 文档进行签名
  • 【UE5 C++课程系列笔记】24——多线程基础——Async
  • MySQL - 子查询和相关子查询详解
  • 低代码平台的集成与扩展性详解
  • 【DevOps工具篇】 SonarQube详解
  • Python Json格式数据处理
  • Swift语言的网络编程
  • cp命令详解
  • JAVA学习-练习试用Java实现“从用户输入获取一个字符串,并使用replace方法将字符串中的所有空格替换为下划线”
  • 深度学习中的卷积和反卷积(一)——卷积的介绍
  • client-go中watch机制的一些陷阱
  • EntityFrameworkCore 跟踪查询(Tracking Queries)
  • 转移指令jmp以及其他转移指令
  • 【Uniapp-Vue3】watch和watchEffect监听的使用
  • 分享一次面试经历
  • 缓存-Redis-API-Redission-自动续期-watch dog
  • 关于FPGA(现场可编程门阵列)工程技术人员的详细介绍
  • 2025最新解决方案:新买的mac鼠标和这个触控板反向
  • 『SQLite』更新和删除表记录