Java封装
1 什么是封装?有什么用?
封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节,但可以通过该对象对外提供的接口来访问该对象。
封装之后就形成了独立实体,独立实体可以在不同的环境中重复使用,显然封装可以降低程序的耦合度,提高程序的扩展性,以及重用性或复用性。外封装可以隐藏内部实现细节,站在对象外部是看不到内部复杂结构的,对外只提供了简单的安全的操作入口,所以封装之后,实体更安全了。
2 封装的代码如何实现
未封装前:
//创建Person类
public class Person {
//年龄
int age;
//姓名
String name;
}
//测试类
public class PersonTest {
public static void main(String[] args) {
//创建Person类对象p1
Person p1 = new Person();
//访问p1的age、name属性值
System.out.println(p1.age);//默认值0
System.out.println(p1.name);//默认值null
//修改p1的age、name属性值
p1.age = 180;
p1.name = "张三";
System.out.println(p1.age);//180
System.out.println(p1.name);//张三
}
}
以上程序Person类未进行封装,其中age、name属性对外暴露,在外部程序中可以对Person对象的age、name随意访问、修改,导致它的不安全,例如人的年龄不可能达到180,但是设置为180时,编译未出现问题,这是不对的。
为了保证数据的安全,这个时候就需要封装,封装的第一步就是将应该隐藏的数据隐藏起来,起码在外部是无法随意访问这写数据的。我们可以使用Java语言中的private修饰符,private修饰的数据表示私有的,私有的数据只能在本类当中访问。
封装后程序:
public class Person {
//年龄
private int age;
//姓名
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 140) {
throw new RuntimeException("输入年龄不合法");
}
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
此时在age、name属性前加了private将其私有,这样在外部程序中是无法对其进行访问的。但是一个对象的属性无法被外部程序访问,自然这个数据就没有存在的价值了,所以就需要封装的第二步:对外提供公开访问的入口,让外部程序统一的从入口去访问数据,在入口处设立关卡,进行安全控制,这样对象内部的数据就安全了。
对于一个数据的使用无非就是”读“和”改“,所以我们应该提供两个访问入口,这两个方法通常被称为set方法和get方法。
测试类:
public class PersonTest {
public static void main(String[] args) {
//创建Person类对象p1
Person p1 = new Person();
//设置name属性值
p1.setName("张三");
System.out.println(p1.getName());
//设置age属性值
p1.setAge(180);
System.out.println(p1.getAge());
}
}
运行结果:

总之,在Java语言中封装的步骤应该是这样的:需要被保护的属性使用private进行修饰,给这个私有的属性对外提供公开的set和get方法,其中set方法用来修改属性的值,get方法用来读取属性的值。并且set和get方法在命名上也是有规范的,规范中要求set方法名是set + 属性名(属性名首字母大写),get方法名是get + 属性名(属性名首字母大写)。其中set方法有一个参数,用来给属性赋值,set方法没有返回值,一般在set方法内部编写安全控制程序,因为毕竟set方法是修改内部数据的,而get方法不需要参数,返回值类型是该属性所属类型。
示例:
/**
* Person类
*/
public class Person {
//年龄
private int age;
//姓名
private String name;
public Person(String _name, int _age) {
name = _name;
age = _age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 测试类
*/
public class PersonTest {
public static void main(String[] args) {
//创建Person类对象p1
Person p1 = new Person("jack", 20);
System.out.println(p1.getName());
System.out.println(p1.getAge());
System.out.println("------------------");
p1.setName("张三");
System.out.println(p1.getName());
p1.setAge(18);
System.out.println(p1.getAge());
}
}
运行结果:

在上段程序中,构造方法已经给属性赋值了,为什么还要提供set方法?
构造方法中给属性赋值是在创建对象的时候完成的,当对象创建完毕之后,属性可能还是会被修改的,后期要想修改属性的值,这个时候就必须调用set方法了。