在上篇文章,我们学习了面向对象的基本概念,这期我们学习面向对象的三大思想之一的封装
首先、我们看下面的代码
class Person {
public String name;
public int age;
public void introduce() {
System.out.println("大家好,我叫" + name + ",今年" + age + "岁");
}
}
public class Demo3 {
public static void main(String[] args) {
// 创建一个 Person 对象,并初始化属性
Person person = new Person();
person.name = "张三";
person.age = 18;
// 调用方法
person.introduce();
}
}运行结果如下:
大家好,我叫张三,今年18岁
进程已结束,退出代码为 0这样一看,代码有没有啥问题,貌似是正确的,那么,我们改一下,传入的age参数为-1呢,再运行代码
大家好,我叫张三,今年-1岁
进程已结束,退出代码为 0我们发现,这种不符合常理的数据也成功被赋值了,为了方便,我们叫这种数据为非法数据,这个时候就引用出来封装的第一个作用,对传入的数据进行过滤处理,或者判断是否成功赋值。
那么如何实现呢,首先属性前面是不是有一个public,这个叫访问修饰符,访问修饰符可以决定资源作为引用类型的时候的访问范围,public是公共的,我们需要转换为私有的,private
class Person {
public String name;
public int age;
public void introduce() {
System.out.println("大家好,我叫" + name + ",今年" + age + "岁");
}
}但是,这个时候,我们对资源就不能进行赋值和取值了,(其实这里引出了封装的第二个作用,确定资源的读取和写入权限),所以我们需要写两个行为(get和set)用于控制写入和读取,如果我们的数值不需要写入或者读取,则可以不写这两个方法,这样就有一个只读或者只写的资源
可以看以下代码
class Person {
private String name;
private int age;
public void SetName(String name) {
this.name = name;
}
public String GetName() {
return this.name;
}
public void SetAge(int age) {
if (age < 0) {
System.out.println("年龄不合法?1");
}
}
public void introduce() {
System.out.println("大家好,我叫" + name + ",今年" + age + "岁");
}
}
public class Demo3 {
public static void main(String[] args) {
// 创建一个 Person 对象,并初始化属性
Person person = new Person();
person.SetAge(-1);
person.introduce();
person.SetAge(20);
person.SetName("张三");
System.out.println(person.GetName());
// 调用方法
person.introduce();
}
}运行结果如下
年龄不合法?1
大家好,我叫null,今年0岁
张三
大家好,我叫张三,今年0岁
进程已结束,退出代码为 0这里我们对age和name都做了访问限制,然后对age提供了set方法,name提供了get和set方法,这个时候,我们的age就不能直接被读取,只能通过调用类行为使用age的数据,然后,可以看到name的get方法,返回了的是我们set的值,而我们在age的set方法中,写了传入参数的处理,这样就对输入做了过滤处理,可以看到,数据的调用并没有解析数据
总结 :
通过上面的学习和代码演示,我们可以得出封装在面向对象编程中的几个重要作用:
提高数据的安全性
使用private修饰属性后,外部无法直接访问或修改对象的内部数据,避免了非法数据的赋值问题。例如:年龄不能为负数、姓名不能为空等。控制属性的访问权限
封装允许我们有选择地对外暴露某些属性的读取或写入权限。例如:只提供
get方法,表示该属性只能读,不能写(只读属性)。只提供
set方法,表示该属性只能写,不能读(虽然这种情况较少)。同时提供
get和set方法,表示该属性可读可写。
增强程序的可维护性和扩展性
通过封装将数据与操作绑定在一起,使得类的使用者不需要关心具体实现细节,只需要按照规定的方法使用即可。如果将来需要修改属性的处理逻辑,只需修改类内部代码,而不会影响到其他使用该类的地方。实现数据的过滤与校验
在set方法中可以加入判断逻辑,对传入的数据进行验证后再决定是否赋值,从而确保数据的合法性和合理性。例如:年龄必须大于0,邮箱格式必须正确等。符合面向对象的设计原则——信息隐藏
类的设计者负责保护类中的数据安全,而使用者只需知道如何调用方法,无需了解内部是如何工作的。这样降低了模块之间的耦合度,提高了程序的健壮性。