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

相关推荐
职略43 分钟前
负载均衡类型和算法解析
java·运维·分布式·算法·负载均衡
A22741 小时前
LeetCode 196, 73, 105
java·算法·leetcode
容若只如初见2 小时前
项目实战--Spring Boot + Minio文件切片上传下载
java·spring boot·后端
阿里巴巴P8资深技术专家2 小时前
Java常用算法&集合扩容机制分析
java·数据结构·算法
weixin_440401692 小时前
分布式锁——基于Redis分布式锁
java·数据库·spring boot·redis·分布式
码农爱java2 小时前
Spring Boot 中的监视器是什么?有什么作用?
java·spring boot·后端·面试·monitor·监视器
zengson_g2 小时前
当需要对大量数据进行排序操作时,怎样优化内存使用和性能?
java·数据库·算法·排序算法
爱上电路设计3 小时前
有趣的算法
开发语言·c++·算法
studyForMokey3 小时前
kotlin 函数类型接口lambda写法
android·开发语言·kotlin
血战灬狂龙3 小时前
pom.xml文件加载后没有变成maven图标
xml·java·maven