Java面向对象编程之 封装性 | Java OOP Encapsulation
Made by Mike_Zhang
Java主题:
0. OOP Introduction
0. 面向对象编程介绍
请阅读本博客的Java面向对象编程详细介绍 - Java OOP Detailed Introduction
1. Definition
1. 定义
封装性 (信息隐藏, Encapsulation) 是OOP的核心思想之一,是将对象的属性和方法打包在一起,并且对其用户隐藏对象内部的实现细节,只留给用户可以操作对象的方法。1
如上图,可以看做一个控制系统对象。程序员把此对象的属性(时间、信号等)与方法(开关、通信、计时等)打包在一个盒子中。留给目标用户的只有最上层的一个开关,用户只需要(只能)操作这个开关就能控制这个系统,无需知道哪内部是如何运作的,也不能对内部的元件进行操作,实现的具体内容留给程序员。
2. Implementations
2. 实现方法
实现封装性的关键是提供方法(Methods)给用户去访问属性(Fields),绝不提供给用户直接访问属性的途径。外部的程序只能通过对象的方法与其内部的属性进行交互。1
封装一个成员属性的具体步骤:
- 定义一个
private
属性; - 定义一个
public
属性访问器(accessor) 方法; - 定义一个
public
属性修改器(mutator) 方法;
常见的应用场景:
- 只读属性(Read-only field):
- 确保某一属性只读,一旦被构造函数被赋值,即不能再被用户改动。否则用户可以随意修改属性,会造成混乱:
1 |
|
- 若用户需要访问某对象的姓名,则:
1 |
|
- 特定条件更新属性:
- 确保某一属性按照特定条件更新,否则会造成混乱:
1 |
|
- 若用户需要让对象长大,则:
1 |
|
3. Benefits
3. 好处
3.1 Security
3.1 确保数据安全
上文提到,属性被设为private
,用户以及外部程序无法直接访问或修改属性,必须通过设计的特定方法进行访问和修改,确保了数据的安全,例如:
1 |
|
若设置age
属性为公共,用户便可以直接访问并修改age
属性,可能会造成错误,例如:
1 |
|
3.2 Reduce Effects from Changing
3.2 减少修改带来的影响
若类内部的实现方法需要发生改变,封装性能够减少此改变对其他类成员、用户、外部程序的影响,例如:1
我需要修改上述例子中name
这一属性,变成姓和名两部分:
1 |
|
从用户的视角对比一下封装带来的好处:
无封装的情况:
- 此情况下,
name
等属性为公开,可被直接访问。
- 此情况下,
1 |
|
- 有封装的情况:
1 |
|
3.3 Error Checking
3.3 提供错误检查
某些属性值需要符合特定的要求,如,年龄需要大于0,薪资不能为负数等。
若直接让用户访问和修改属性,则可能会出现违反要求的情况,会造成错误。因此封装能确保用户在这些要求下进行操作,并及时检查错误行为,例如:1
- 无封装的情况:
1 |
|
1 |
|
- 有封装的情况:
1 |
|
1 |
|
会发现封装性有一点“绕圈子”,明明可以直接访问属性,却要用一个额外的方法去返回这个属性。
确实,如果你的对象只需要实现一些很简单的功能,不会有后续的改动,不会有外部的用户,你无需使用封装,你甚至无需使用OOP。
但是,如果你的功能复杂度很高,用户很多,需要一直改动,不断添加新的功能,那好的封装会提高你代码的复用性、可靠性和安全性等。
References
引用
1. C. S. Horstmann, Core Java. Boston: Pearson, 2019. ↩
2. M. Goodrich, R. Tamassia, and A. O’reilly, Data Structures and Algorithms in Java, 6th Edition. John Wiley & Sons, 2014. ↩
Outro
尾巴
Java中OOP相关的知识是十分重要的, 会继续更新.
最后,希望大家一起交流,分享,指出问题,谢谢!
原创文章,转载请标明出处
Made by Mike_Zhang