面向对象第二大特征:封装/隐藏
一、隐藏/封装(encapsulation)
- 为什么需要封装?封装的作用和含义?
- 比如:①我要看电视,只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?②我要开车,……
- 隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可拓展性、可维护性。
- 我们程序设计要追求“高内聚、低耦合”
- 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;
- 低耦合:仅暴露少量的方法给外部使用
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节(当然也无从知道),但可以通过该对象对外的提供的接口来访问该对象。
二、使用访问控制符,实现封装
Java中的控制符,用来控制其他类能否访问Java中的某一方法、变量,即控制java类、方法、变量的可见性、可访问性,从而实现数据封装。
Java中有两个级别的访问控制符。
- 类级别:控制其他类能否使用该类。有2中类型: public 和 package-private(default)
- 成员级别:控制某一方法、变量的访问权限。有4种类型: public , protected, package-private(default), private。
类级别:
成员级别:
(一) 封装的要点:
(类里面主要是属性和方法)
Java提供了访问权限控制: private->default->protected->public(权限依次扩大)来封装内部属性和提供外部接口(对字段采用private或protected等修饰符来限制,采用getter和setter来进行有效控制)。
- 类的属性的处理:
-
- 一般使用private。(除非本属性确定让子类继承);静态变量、常量可以public
- 针对private的属性,提供相应的get/set方法来访问相关属性,这些方法通常是public,从而提供对属性的读取操作。(一般get/set方法的写法:getXX(); setXX(); 注意:boolean变量的get方法是用:is开头!如isXX(),set方法还是setXX())
- 一些只用于本类的辅助性方法可以用private。
- 希望其他类调用的方法用public。
【示例1】private测试:
同在一个包内的test01和test02
test01类:
test02类:
不可以在同一包其他类中调用私有成员或方法。但是可以在同一类中调用。
【示例2】default(默认,什么都不加)测试:
同一个包内:(test01和test02在一个包内)
把test01类的print()方法前面的控制符private去掉,则在test02类中就可以调用
不同包内:(test01和test02在一个包内,test03在另外的包)
【示例3】protected测试:其他包的子类可以访问。
示例代码的位置图:
在同一个包内,而且是test01的子类,可以访问。
但是在其他包,不是子类,就不可见。
在其他包是test01的子类,可以访问print()
【访问控制符总结】
private修饰的成员,在同一类中可见;
default(默认,成员前面没有加控制符),则是同一类和同一包下面的类可见。
protected修饰的成员,在同一个类、同一个包下面的类可见,并且在不同包的子类也可见。
public修饰的成员在所有类都可见。