1.什么是封装
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节(当然也无从知道),但可以通过该对象对外的提供的接口来访问该对象。<通过合并特征和行为来创建新的数据类型>
简单讲就是将属性私有化,提供公有的方法访问私有属性。如:
<span style="font-size:18px;">
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
</span>
2.为什么要封装
1. 实现对属性的数据访问限制,同时增加了程序的可维护性;
2. 隐藏方法和赋值实现细节,可以使我们容易地修改类的内部实现,而无需修改该类的客户端代码;
3. 可以对成员变量进行更精确的控制。
3.举个栗子
<span style="font-size:18px;">
public class Person {
/*
* 对属性的封装
* 一个人的姓名、性别、年龄、妻子都是这个人的私有属性
*/
private String name ;
private String sex ;
private int age ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
//提现出可以对成员变量进行精准的控制
if(age>130||age<0){
System.out.println("ERROR:error age input....");
}
this.age = age;
}
//构造方法 构造方法可以简化对象初始化,为实例变量赋值
Person(String name,String sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
}
}</span>
***this关键字
有时一个方法需要引用调用它的对象,为此Java定义this关键字,简单说this是在对象内部指代自身的作用,可以直接引用对象,解决实例变量与局部变量之间的同名冲突问题。
4.不要编写返回可变对象的访问器方法
在上例中加入出生日期
<span style="font-size:18px;">
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
</span>
这段代码粗看没有什么问题,再看引用时代码
<span style="font-size:18px;"> Person p = new Person("LL", "男", 18,new Date(2013,10,11) {
});
Date d = p.getBirthday();
d.setTime((long)30*365*24*3600*1000);
System.out.println(p.getBirthday());</span>
输出结果
<span style="font-size:18px;">Sat Dec 25 08:00:00 CST 1999</span>
实际上这样会破坏封装性。出错的原因很微妙,因为d和p.getBirthday()应用了同一个对象,对d调用更改器方法就可以自动改变这个对象的私有状态!
解决方案:
如果需要返回一个可变对象的引用,应该首先对它进行克隆(clone)。修改后代码如下:
....
public Date getBirthday() {
return (Date) birthday.clone();
}
...