Java——封装(Encapsulation)

一、封装简介

1、封装是什么

封装(Encapsulation) 是面向对象编程(OOP)中的一个基本概念,它指的是将对象的状态(数据)和行为(方法)绑定在一起,并对外隐藏对象的内部细节。在Java中,封装通过使用访问修饰符(如 privateprotectedpublic)来实现,这些修饰符控制类的成员(变量和方法)的可见性和访问级别。封装在Java中确实涉及将类的部分实现细节(包括数据和方法)隐藏起来,只对外暴露必要的抽象接口。

封装可以被视为一种保护屏障,它通过限制外部代码对类内部数据和方法的直接访问,提供了对类的内部实现的保护。要访问该类的代码和数据,必须通过严格的接口控制。封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

打个比较生动的例子就是当我们使用手机时,我们不需要了解其内部电路、处理器、内存或其他硬件组件的具体工作原理。相反,我们只需要使用手机提供的各种功能和应用程序,如拨打电话、发送短信、浏览网页、拍照等。

2、封装的好处

  • 提高安全性:通过隐藏内部数据,可以防止外部代码直接操作数据,从而减少错误和提高安全性。
  • 简化代码的使用:使用者只需要知道类的公共接口,而不需要了解内部实现细节。
  • 易于修改和维护:类的内部实现可以自由修改,而不影响使用该类的其他代码。

二、封装的详细步骤

1. 将属性进行私有化(private)

java 复制代码
class Person {
	private String name;
	private int age;
}

2. 提供一个公共的 set 方法,用于对属性判断并赋值

java 复制代码
class Person {
	private String name;
	private int age;

	public void setName(String name) {
		if(name != null && name.length() >= 2 && name.length() <= 6) {
			this.name = name;
		} else {
			throw new IllegalArgumentException("名字长度应当在 2-6 个字");
		}
	}

	public void setAge(int age) {
		if(age >= 0 && age <= 200) {
			this.age = age;
		} else {
			throw new IllegalArgumentException("年龄应当在 0-200 之间");
		}
	}
}

3. 提供一个公共的 get 方法,用于获取属性的值

java 复制代码
class Person {
	private String name;
	private int age;

	public void setName(String name) {
		if(name != null && name.length() >= 2 && name.length() <= 6) {
			this.name = name;
		} else {
			throw new IllegalArgumentException("名字长度应当在 2-6 个字");
		}
	}

	public void setAge(int age) {
		if(age >= 0 && age <= 200) {
			this.age = age;
		} else {
			throw new IllegalArgumentException("年龄应当在 0-200 之间");
		}
	}

	public int getAge() {
		return age;
	}

	public String getName() {
		return name;
	}
}

示例

java 复制代码
package com.pack1;

public class Encapsulation {
	public static void main(String[] args) {
		Person person = new Person();
		person.setName("张三");
		person.setAge(18);
		System.out.println("名字:" + person.getName() + "\n年龄:" + person.getAge());
	}
}

class Person {
	private String name;
	private int age;

	public void setName(String name) {
		if(name != null && name.length() >= 2 && name.length() <= 6) {
			this.name = name;
		} else {
			throw new IllegalArgumentException("名字长度应当在 2-6 个字");
		}
	}

	public void setAge(int age) {
		if(age >= 0 && age <= 200) {
			this.age = age;
		} else {
			throw new IllegalArgumentException("年龄应当在 0-200 之间");
		}
	}

	public int getAge() {
		return age;
	}

	public String getName() {
		return name;
	}
}

运行结果:

可以发现这里我们可以使用 setter 对私有属性进行配置,可以使用 getter 对私有属性进行获取。而不是直接对属性进行访问。

三、补充

1、构造器与 setter 相结合

我们可以在构造器中使用 setter 已保留那些对属性设置的验证逻辑,也就是保留那些防护机制。

java 复制代码
package com.pack1;

public class Encapsulation {
	public static void main(String[] args) {
		try {
			Person person = new Person("张三",18); // 合法姓名和年龄
			System.out.println("姓名: " + person.getName() + "\n年龄" + person.getAge());

			// 非法姓名,将引发异常
			Person person2 = new Person("",18);
		} catch (IllegalArgumentException e) {
			System.out.println(e.getMessage());
		}
	}
}

class Person {
	private String name;
	private int age;

	//使用 setter 的构造器
	public Person(String name, int age) {
		setName(name);
		setAge(age);
	}

	public void setName(String name) {
		if(name != null && name.length() >= 2 && name.length() <= 6) {
			this.name = name;
		} else {
			throw new IllegalArgumentException("名字长度应当在 2-6 个字");
		}
	}

	public void setAge(int age) {
		if(age >= 0 && age <= 200) {
			this.age = age;
		} else {
			throw new IllegalArgumentException("年龄应当在 0-200 之间");
		}
	}

	public int getAge() {
		return age;
	}

	public String getName() {
		return name;
	}
}

运行结果:

可以发现这里使用构造器传入错误的参数依旧会抛出异常,可以发现将构造器与 setter 相结合使用可以保留对参数的验证。

相关推荐
blueSatchel8 分钟前
U-Boot载入到DDR过程的代码分析
linux·开发语言·u-boot
专注VB编程开发20年10 分钟前
vb.net datatable新增数据时改用数组缓存
java·linux·windows
(>_<)13 分钟前
java minio 分片上传工具类与测试demo
java·minio·分片上传
不想打工的码农13 分钟前
MyBatis-Plus多数据源实战:被DBA追着改配置后,我肝出这份避坑指南(附动态切换源码)
java·后端
无小道17 分钟前
QT——QFIie和QFileInfo文件类
开发语言·qt·命令模式
Coder_Boy_29 分钟前
Deeplearning4j+ Spring Boot 电商用户复购预测案例
java·人工智能·spring boot·后端·spring
踢足球092937 分钟前
寒假打卡:2026-2-7
java·开发语言·javascript
闻哥40 分钟前
Kafka高吞吐量核心揭秘:四大技术架构深度解析
java·jvm·面试·kafka·rabbitmq·springboot
金牌归来发现妻女流落街头41 分钟前
【Springboot基础开发】
java·spring boot·后端
考琪1 小时前
Nginx打印变量到log方法
java·运维·nginx