封装概述
现实生活中,每一个个体与个体之间是有边界的,每一个团体与团体之间是有边界的,而同一个个体、团体内部的信息是互通的,只是对外有所隐瞒。
面向对象编程语言是对客观世界的模拟,客观世界里每一个事物的内部信息都是隐藏在对象内部的,外界无法直接操作和修改,只能通过指定的方式进行访问和修改。
封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。
面向对象的开发原则要遵循“高内聚、低耦合”,而“高内聚,低耦合”的体现之一:
-
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
-
低耦合:仅对外暴露少量的方法用于使用
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
如何实现封装呢?
通俗的讲,封装就是把该隐藏的隐藏起来,该暴露的暴露出来。那么暴露的程度如何控制呢?就是依赖权限修饰符来控制。访问控制修饰符来控制相应的可见边界,边界有如下:
- 类
- 包
- 子类
- 模块:Java9之后引入
权限修饰符如下图所示
注意事项:
- protected修饰非静态成员,跨包时,只能在子类的非静态成员中访问,在静态成员中无论是否创建对象都不能访问。
封装成员变量
成员变量封装的目的
- 隐藏类的实现细节
- 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里面加入控制逻辑,限制对成员变量的不合理访问。还可以进行数据检查,从而有利于保证对象信息的完整性。
- 便于修改,提高代码的可维护性。主要说的是隐藏的部分,在内部修改了,如果其对外可以的访问方式不变的话,外部根本感觉不到它的修改。
成员变量(field)私有化之后,提供标准的get/set方法,我们把这种成员变量也称为属性(property)。或者可以说只要能通过get/set操作的就是事物的属性,哪怕它没有对应的成员变量。
实现步骤
1:使用 private 修饰成员变量
/*
格式:private 数据类型 变量名 ;
*/private String name;private static String nationality;
2:提供 getXxx方法 / setXxx 方法,可以访问成员变量,代码如下:
public class Student {private String name;private static String nationality;// 获取成员变量的值public static String getNationality() {return nationality;}// 设置成员变量的值public static void setNationality(String nationality) {Student.nationality = nationality;}// 获取成员变量的值public String getName() {return name;}// 设置成员变量的值public void setName(String name) {this.name = name;}
}
setXxx 方法出现的this是什么意思?为了解决局部变量与成员变量同名问题
- 当局部变量与类变量同名时,在类变量前面加“类名.";
- 当局部变量与实例变量同名时,在实例变量前面加“this.”
实例
public class Test {public static void main(String[] args) {Student student = new Student();student.setName("张三");Student.setNationality("中国");System.out.println(student.getName()); //张三System.out.println(Student.getNationality()); //中国}
}
构造器
我们发现我们new完对象时,所有成员变量都是默认值,如果我们需要赋别的值,需要挨个为它们再赋值,太麻烦了。我们能不能在new对象时,直接为当前对象的某个或所有成员变量直接赋值呢。可以,Java给我们提供了构造器。
构造器的作用
在创建对象的时候为实例变量赋初始值。构造器只为实例变量初始化,不为静态类变量初始化
构造器的语法格式
构造器又称为构造方法,那是因为它长的很像方法。但是和方法还有有所区别的。
代码如下:
public class Student {private String name;private static String nationality;// 有参构造public Student(String name) {this.name = name;}// 无参构造public Student() {}// 其他代码}
注意事项:
-
构造器名必须与它所在的类名必须相同。
-
它没有返回值,所以不需要返回值类型,甚至不需要void
-
如果你不提供构造器,系统会给出无参数构造器,并且该构造器的修饰符默认与类的修饰符相同
-
如果你提供了构造器,系统将不再提供无参数构造器,除非你自己定义。
-
构造器是可以重载的,既可以定义参数,也可以不定义参数。
-
构造器的修饰符只能是权限修饰符,不能被其他任何修饰