1.概述
学习了前面的面向对象的基础概念后,我们了解要以面向对象的思维来思考一个事物。面向对象有三个基本属性:封装、继承、多态。今天我们就重点讲解其中一个封装
的概念。
抛开”封装“这个名词,我们一步一步来思考下面的问题:
2. 问题
我们定义一个学生类,它有姓名、年龄属性,
class Student{
String name;
int age;
}
为了看到这两个属性的值。我们再定义一个方法,把这两个属性显示出来。
public void show(){
System.out.println("姓名"+name);
System.out.println("年龄"+age);
}
我们再定义一个测试类StudentDemo,创建一个学生对象来调用上面的show方法,发现我们也可以对这个学生对象的属性进行赋值和修改。
public class StudentDemo {
public static void main(String[] args) {
// 创建学生对象
Student s = new Student();
s.show();
System.out.println("---------");
// 给成员变量赋值
s.name = "小雨";
s.age = 27;
s.show();
System.out.println("---------");
// 给年龄赋值
s.age = -27; // 这个数据时不合理的
s.show();
System.out.println("--------");
}
}
我们发现,通过对象给成员变量直接赋值,居然可赋一些非法的值,比如给年龄设置一个负数,显然这是不合理的。
我们想应该是这样子比较好,在赋值之前,先定义一个校验函数,对数据进行判断。
那么这个校验函数到底在哪里写做比较合适呢?
StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。它只负责测试和调用,属性的判断应该放进原始的Student类中比较好,所以这个判断应该定义在Student类中。而我们在成员变量的位置可不可以进行数据判断呢?
显然是不可以的,因为做数据校验,必须要依靠一些逻辑语句。逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中写一个方法进行校验。
// 写一个方法对数据进行校验
/*
返回这类型:void
参数列表:int a
*/
public void setAge(int a){
if (a<0 || age>120){ // 一个人的年龄应该在0~120之间
System.out.println("你给的年龄有问题");
}else{
age = a;
}
}
按照上面我们的分析,我们给出这个方法进行校验输入的值。但是呢?此时,系统仍然可以通过对象来修改属性。还是可以直接赋值。这样我们定义的校验方法就起不到作用,我们应该要求你必须使用我的校验方法,而不能直接调用成员变量进行赋值。
怎样才能强制要求不能直接使用成员变量呢?
针对这种情况,Java就提供了一个用来修饰成员变量和成员方法的关键字private
,表示私有的意思。
表示被private
修饰的成员只能在本类中访问。
其实我们将到现在,讲的就是一个封装的思想,它表示隐藏对象的属性和实现细节,仅对外提供公共访问的方式。
最终版的代码如下:
class Student{
String name;
private int age;
// 写一个方法对数据进行校验
/*
返回这类型:void
参数列表:int a
*/
public void setAge(int a){
if (a<0 || age>120){
System.out.println("你给的年龄有问题");
}else{
age = a;
}
}
// show()方法,显示所有成员变量的值
public void show(){
System.out.println("姓名"+name);
System.out.println("年龄"+age);
}
}
public class App {
public static void main(String[] args) {
// 创建学生对象
Student s = new Student();
s.show();
System.out.println("---------");
// 给成员变量赋值
s.name = "swift";
// s.age = 27;
s.show();
System.out.println("---------");
// 给年龄赋值
// s.age = -27; // 这个数据时不合理的
s.setAge(-27);
s.show();
System.out.println("--------");
}
}
小结:
封装将不需要对外提供的内容都隐藏起来,把属性隐藏,提供公共方法对其访问。好处就是:隐藏实现细节,提供公共的访问方式;提高了代码的复用性;提高了安全性。
网友评论