通过使用权限修饰符,我们可以限定类的成员的被访问权限,那为什么要这样做呢?在很多场景下,我们需要确保我们对属性值的操作均是有效操作,不能违背某些规则。
比如,我们定义了一个Person类,具有name和money两个属性,在买东西时需要扣掉相应的金额,原始写法如下:
public class Person{
public String name;
public double money;
}
public class Test{
public static void main(String[] args){
Person person = new Person();
person.money = 500;// 初始金额500元
System.out.println("购买一张桌子,花费200元");
person.money -= 200;
System.out.println("购买二手PSP,花费350元");
person.money -= 350;
System.out.println("目前余额为:" + person.money);// -50
}
}
可以看到,经过代码操作以后可能会导致money的属性为负。看官甲:你自己不加判断赖代码?没错,这个问题我们可以增加判断代码来解决,由于这个操作是对money属性值的操作,我们将它封装成一个方法写在实体类中,于是有了改进之后的代码:
public class Person{
public String name;
public double money;
// 定义一个方法,用于设置money属性的值
public void setMoney(double money){
if(money >= 0){
this.money = money;
}
}
}
public class Test{
public static void main(String[] args){
Person person = new Person();
person.money = 500;// 初始金额500元
System.out.println("购买一张桌子,花费200元");
person.setMoney(person.money - 200);
System.out.println("购买二手PSP,花费350元");
person.setMoney(person.money - 350);
System.out.println("目前余额为:" + person.money);// 300
}
}
经过上面的改进,我们可以确保money的值不为负数,同时可以看到,当在实体类中定义方法后,使用者需要修改属性值时直接调用方法就可以保证不出问题。但是由于属性值依然可以被直接访问,还不能保证万无一失,于是我们利用权限修饰符使得变量不能被直接访问,同时需要定义一个能够取得属性值的方法。
public class Person{
public String name;
// 声明money属性为private权限
private double money;
// 定义一个方法,用于设置money属性的值
public void setMoney(double money){
if(money >= 0){
this.money = money;
}
}
// 定义一个方法,用于获取money属性的值
public double getMoney(){
return this.money;
}
}
public class Test{
public static void main(String[] args){
Person person = new Person();
person.setMoney(500);// 初始金额500元,此时已经不能使用对象.属性的方法赋值
System.out.println("购买一张桌子,花费200元");
person.setMoney(person.getMoney() - 200);
System.out.println("购买二手PSP,花费350元");
person.setMoney(person.getMoney() - 300);
System.out.println("目前余额为:" + person.getMoney());// 300
}
}
通过以上的案例,我们可以看到进行封装有以下几个作用:
防止类的属性被外部代码随意的修改和访问,保证数据的完备性
将对属性的操作转换为方法,更加灵活和安全
使用封装可以隐藏实现的细节:使用者只需要作用,不需要知道过程
在类的定义结构中修改,提高了代码的可维护性,同时又可以不影响外部的使用
通过封装方法可以有效减少耦合
耦合:模块与模块之间,代码与代码之间的关联程度,对属性封装后,和调用相关的代码就会变得相对简单,可以降低耦合。