上节课我们学习了面向对象编程的基本理念和类与对象的基本抽象设计。
但是,在实际的开发过程中,会用到面向对象的编程的封装理念。
为什么呢?举个例子。
A和B是朋友,但是:
1、A在脑子里想的东西B是不知道的。
2、B要知道A想什么,就要通过A通过语言叙述给他。
3、如果A想的东西不想让B全部知道,可以省略一些。也可以不说怎么想的,只说一个结果。
4、A怎么想的对B是完全不可见的。
这个现实的情况在用程序描述业务时也是必须的,他在一定程序上就体现了封装的特性。
我们来看看今天的内容:
1、对象封装
2、封装的特点
3、封装的实现
第一部分:对象封装
封装,即:
1、将对象抽象得到的数据和行为(或功能)相结合,形成一个有机的整体。也就是将数据与操作数据的方法进行有机的结合,形成“类”。
2、隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中对象属性的读和修改的访问。
第一个点很好理解,我们平时说一个人,一个动物,一件衣服,都是把他们按照一个整体来研究的,不会胳膊腿分开来研究。
一个衣服的颜色不好,你不喜欢,那这个衣服你就不会买。他们都是一个整体,别人在研究它是都看成一个独立的个体。
那么,面向对象程序也是将研究的对象打包成这样的一个个个体,你直接和这个对象打交道,调方法属性去用。
这个点呢,就要求我们要能够对对象的属性和方法合理抽象,并且将他们打包在一起,形成一个类对象。
第二点呢,其实也比较好理解,我们开头举的例子,人的思考别人是不知道的。
相应的,程序里边对其他对象没有影响的行为方法我们都可以隐藏起来,只提供一些别人需要和我们交互的行为,比如说话。
那么,这个点就要求我们能够做到对程序对象的行为足够理解,能够分开开放的、隐藏的行为方法。
至于怎么隐藏我们下面会说。
第二部分:封装的特点
封装是一种编程思想,不是一种实践技术。我总结了下,它主要有以下4个特点:
1、面向对象编程时,将对象的属性和行为封装起来,结合成一个独立的完整的单位。对象属性只能通过对象来访问或修改。
2、隐蔽对象的内部细节,外部不可见内部的细节,与外部的联系只能通过对象的对外接口交互。对外形成一道屏障,对象对外有安全控制。
3、对象之间的关系不同,他们之间的属性和行为可见性也不同。
3、封装减少了内部的改变对外部的影响。
这三个特点其实非常简单但深刻,需要大量的实践慢慢体会。我们第三部分来了解下如何实现对象的封装,体现对象封装的特点。
第三部分:封装的实现
封装这个特性需要借助java的访问权限控制关键字和抽象的思路来实现。封装的过程就是封装的特点体现的过程。我们还是以人为例子来举例。
第一步:把人这个对象抽象出来,包括他的属性和行为,将他们放在一个类里,形成一个整体。
那我们来思考,人的属性有:姓名,性别,年龄,身高,体重等等,行为有吃饭,睡觉,说话,思考等等。
我们把这些翻译成java 的类,使用变量和方法描述一下。
class Person{
String name;
String sex;
int age;
int heigth;
float weight;
void eat(){
}
void sleep(){
}
void talk(){
}
void thinking(){
}
}
这样,我们对一个对象的第一步就完成了。把人这个对象的属性和行为组织起来,形成了一个类对象。
别人要想访问Person,就得通过new Person获取对象,通过对象来操作Person 的属性方法。
不能绕过对象直接调用。因为他们是一个整体。
体现第一个特点。
那么,接下来,我们需要对他的属性和行为进行分析,把需要交互的行为暴露出来,私有的行为隐藏起来。
第二步:行为和属性的隐藏开放
我们思考下,一个人的属性都是他自己的标签,他叫什么名字,年龄多大,身高体重多少,一般都需要他告诉你,不然你肯定不知道。
所以,对于一个对象,他的属性一般都是私有的。那在java中私有怎么表示呢?
我们之前学过访问权限控制符,那就知道,私有需要借助关键字private来描述。这时候我们就用它来修饰下属性。
另外呢,行为也一样,我们想想,我们吃饭睡觉说话别人都是可以看见的,但是思考是不是看不见,所以,思考是私有的行为。
我们将以上的属性和行为用程序描述出来。
class Person{
private String name;
private String sex;
private int age;
private int heigth;
private float weight;
void eat(){
}
void sleep(){
}
void talk(){
}
private void thinking(){
}
}
现在,Person 的属性和thinking就被私有化了,隐藏了起来,外部不可见。
体现了第二个特点。
但是呢,对于一些行为,对象之间的关系不同,行为也会不同。比如牵手、拥抱、接吻。
牵手呢,可以发生在你和老人、小孩、朋友、亲人、爱人之间。
拥抱呢,发生在你和哥们闺蜜、亲人、爱人之间。
接吻呢,发生在爱人之间。
这样一来,对象和对象的关系不同,那么他们之间可以发生的行为也不同。
在java语言当中,也是支持这种行为的级别控制的。
我们之前学习的访问控制符除了私有private,还有默认,protected,public。他们就可以帮助我们完成。
我们回忆下:
public:程序内所有对象可见
protected:包内或子类可见
默认:没有修饰符,包内可见。
所以,我们根据对象的关系区别,将他们设计为合适的包或子类关系,就能达到方法的访问控制级别。
由于此处示例的话代码太多,我们就演示代码。自己测测访问权限。
class Person{
//私有属性
private String name;
private String sex;
private int age;
private int heigth;
private float weight;
//程序内开放行为
public void eat(){
}
public void sleep(){
}
public void talk(){
}
//包内和子类开放
protected void hug(){
}
//包内开放
void kiss(){
}
//私有行为
private void thinking(){
}
}
这个也体现了封装的第3个特点。不同的关系不同的访问权限。
至此呢,封装已经完成。但是封装的第四个特点,他是一个相对结论。内部对外部隐藏,外部不可见。
相对的,外部看不得内部,内部隐藏的行为发生什么变化对外没有影响,不影响程序的对象关系稳定。
你一会想上天,一会想入地,对别人有什么影响呢?
我们用个例子演示下。。。
第一次,我们让Person对象的思考方法打印“我在思考人生”,然后让外部对象通过开发接口访问。
class ThinkPerson{
private void thinking(){
System.out.println("我在思考人生");
}
public void tellMeThinking(){
thinking();
}
}
public static void main(String[] args) {
ThinkPerson you = new ThinkPerson();
you.tellMeThinking();
}
第二次,我们让Person对象的思考方法打印“我在想吃啥”,然后仍然用外部接口访问Person对象,接口没变化,其他对象和Person的关系还是没有变化。
class ThinkPerson{
private void thinking(){
System.out.println("我在想吃啥");
}
public void tellMeThinking(){
thinking();
}
}
public static void main(String[] args) {
ThinkPerson you = new ThinkPerson();
you.tellMeThinking();
}
到此,,java 的封装就告一段落了。。大家明白这种思想了吗?
封装不是使用权限控制符,而是一种思想。