先给出一个“个人”类和一个测试类。
public class Person {
int age;
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.age = 10;
System.out.println(person.age);
person.age = 20;
System.out.println(person.age);
person.age = -30;
System.out.println(person.age);
}
}
//通过运行可以发现的,结果分别是10、20、-30。但程序存在着缺陷,因为一个人的年龄不可能为负数,程序运行中也没有报错。
对于当前程序来说:
1)Person类中的age属性可以在外部程序中随意访问,导致age属性的不安全。
2)一个Person对象表示一个人,人的年龄不可能为负数,程序运行时也没有报错这是程序存在的缺陷。
当前我们讲的是封装机制,那么我们为什么要封装?封装有什么好处?
理解封装的好处就能知道我们为什么要封装。
封装的好处:
1)封装之后,我们看不到被封装的事物的复杂的一面,只能看到该事物简单的一面。复杂性封装,对外提供简单的操作入口。照相机就是一个很好的封装案例,照相机的原理非常复杂,但是对于使用照相机的人来说,使用照相机是非常简单便捷的。还有电视机也是封装的,电视机内部是非常复杂的,但是使用者只需要使用遥控器,不需要理解内部复杂原理。
2)封装之后才会形成真正的“对象”,真正的“独立体”。
3)封装就意味着以后的程序可以重复使用,并且这个事物应该适应性比较强,在任何场合都可以使用。
4)封装之后,对于事物本身,提高了安全性。没封装就像电视机没有后盖,很容易破坏电视机内部,但是封装过后,安全性提高了,并且在外部不管怎么按遥控器的按钮,都不会对电视机内部造成破坏。
回过头来看 person.age = -30; 这里的age属性显然是完全暴露给外部程序的,对于程序员来说可以操作Person对象当中所有的细节,导致Person对象中部分数据不安全。我们建议对Person类型进行封装,在外部程序中不能随意访问Person对象当中的属性。这样可以保证属性的安全。
那怎么对代码进行封装呢?
封装的步骤:
1)所有的属性私有化,使用private关键字进行修饰,private表示私有的,只能在本类中进行访问。
- 在属性私有化之后,属性非常安全,以至于无法在Test类中进行访问。age属性在外部彻底访问不到了。
2)对外提供简单的操作入口,也就是说外部程序想要访问age属性,必须通过这些简单的入口进行访问:
- 对外提供两个公开的方法,分别是setter方法和getter方法。
- 想修改age属性,调用setter方法。
- 想读取age属性,调用getter方法。
3)settr方法命名规范:
public void setAge (int age){
this.age = age;
}
4)getter方法命名规范:
public void getAge (){
retrun age;
}
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(-100);//封装后不可以再用person.age = 100;的方法进行访问
System.out.print(person.getAge());
}
}
我们对代码进行了封装,但是这个程序的结果仍然是-100,这个封装没有起到我们想要的作用。关键的地方在于,在setter方法中编写业务逻辑代码进行安全控制。
//修改后:
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age < 0 || age > 150) {
System.out.println("对不起,您提供的年龄不合法");
return;
}
this.age = age;
}
}
End...