类的封装
一、案例描述
1、 目标
了解为什么要对类进行封装
了解如何实现类的封装
2、 分析
在上一个案例中,s1对象的年龄是可以随便赋值的,如果将age的值赋值为-30,显然违背了事实。为了解决这类问题,我们需要对类进行封装,防止外界对类中的成员变量随意访问。为了让初学者更好地掌握类的封装,本案例将使用private关键字对成员变量name和age进行私有化,同时分别提供一个setName(String n)和setAge(int a)方法用于外界的访问,其中setAge(int a)中需要对age进行判断。
3、 设计思路(实现原理)
(1) 编写测试类Example02,将属性age的值设为-30,演示不合理现象。
(2)对Student类进行修改,将name和age属性使用private修饰,然后定义getName()、setName(String n)、getAge()和setAge(int a)四个对外访问name和age的方法。
(3) 在setAge(int a)方法中对传入的参数进行检查,如果输入值为负数,则打印出“设置的年龄不合法”,如果不为负数,才将其设置为age属性的值。
(4)对Example02类进行修改,在main()方法中创建Student类的实例对象,通过调用对象的setName(String n)和setAge(int a)方法来设置的name属性和age属性值,并调用speak()方法。
二、案例实现
1、定义Example02类,代码如下所示:
public class Example02 {
public static void main(String[] args) {
Student s1 = new Student();
s1.name = "小新";
s1.age = -30;
s1.speak();
}
}
运行结果如图所示:
从上图可以看出,当将age的值设置为-30后,程序不会报错,但却违背了现实。
2、对Student类进行封装,其代码如下:
class Student {
private String name = "张三";
private int age = 19;
public String getName() {
return name;
}
public void setName(String n) {
name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
// 对传入的参数进行检查
if(a < 0){
System.out.println("设置的年龄不合法");
}else{
age = a;
}
}
void speak() {
System.out.println("我的名字是" + name + ",今年" + age + "岁");
}
}
public class Example02 {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("小新");
s1.setAge(-30);
s1.speak();
}
}
运行结果如下图所示:
三、案例总结
1、Student的name和age属性使用private关键字修饰为私有后,在Example02类中不能再使用s1.name和s1.age的方式访问这两个属性,只能通过public类型的setName(String n)和setAge(int a)方法进行访问。在上面的代码中,调用setAge(int a)方法时的传入参数为-30,由于参数小于0,会打印出“设置的年龄不合法”,并不会将负数赋值给age属性。由此可见,只要实现了封装就能对外界的访问进行控制,避免对私有变量随意修改而引发问题。
2、思考一下:定义一个Division类(除法),类中定义两个int类型的私有成员变量dividend(被除数)和
divisor(除数),默认值都为1。定义四个公有方法setDividend(int mDividend )、getDividend()、setDivisor(int mDivisor)和getDivisor(),用于对私有属性进行设置和访问。在setDivisor(int mDivisor)方法中对传入的参数进行检查,如果传入值为零,则打印“除数不能为零”,如果不为零,才将其设置为divisor属性的值。
定义Example03类,在类的main()方法中创建Division对象,分别调用setDividend(int mDividend)和setDivisor(int mDivisor)方法给两个私有属性dividend和divisor赋值,然后打印出dividend和divisor的结果。
(1)定义Division类,代码如下所示:
public class Division {
private int dividend = 1;
private int divisor = 1;
public void setDividend(int mDividend) {
dividend = mDividend;
}
public int getDividend() {
return dividend;
}
public void setDivisor(int mDivisor) {
if (mDivisor == 0) {
System.out.println("除数不能为零");
} else {
divisor = mDivisor;
}
}
public int getDivisor() {
return divisor;
}
}
(2)定义Example03类,代码如下所示:
public class Example03{
public static void main(String[] args) {
Division division = new Division();
division.setDividend(10);
division.setDivisor(0);
int dividend = division.getDividend();
int divisor = division.getDivisor();
System.out.println(dividend / divisor);
}
}
运行结果如下图所示。
从运行结果可以看出,由于实现了Division类的封装,在setDivisor(int mDivision)方法中对传入的值进行检查,从而避免程序中出现除数为0的错误。