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 相结合使用可以保留对参数的验证。

相关推荐
User_芊芊君子5 分钟前
CANN010:PyASC Python编程接口—简化AI算子开发的Python框架
开发语言·人工智能·python
苏渡苇6 分钟前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
团子的二进制世界12 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法
Max_uuc16 分钟前
【C++ 硬核】打破嵌入式 STL 禁忌:利用 std::pmr 在“栈”上运行 std::vector
开发语言·jvm·c++
故事不长丨16 分钟前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long31617 分钟前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
牵牛老人19 分钟前
【Qt 开发后台服务避坑指南:从库存管理系统开发出现的问题来看后台开发常见问题与解决方案】
开发语言·qt·系统架构
froginwe1128 分钟前
Python3与MySQL的连接:使用mysql-connector
开发语言
rannn_11144 分钟前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
灵感菇_1 小时前
Java HashMap全面解析
java·开发语言