Java 封装学习总结
本章学习目标
-
重点掌握封装的作用
-
掌握 private 关键字含义和基本用法
-
掌握 this 关键字的含义和基本用法
-
掌握 static 关键字的含义和基本用法
-
掌握导入 jar 包
封装
什么是封装
一句话,封装就是对外部隐藏内部细节
封装的作用
-
封装可以隐藏大量内部细节降低外部用户使用难度
-
封装可以使修改内部细节不影响外部用户的使用
-
封装可以降低内部组件之间的耦合度便于维护
private 和 public 关键字
Java 语言中提供了两个权限访问修饰符,分别是 private 和 public,它们专门实现 Java 对象的封闭和开放。
public 访问修饰符
public 表示公用的,也就是对外公开
public 访问修饰符可以修饰类、成员变量和方法,代码如下:
public class Man {
public int age;
public String name;
public void play() {
System.out.println("喜欢打游戏");
}
}
以上代码在类、成员变量和方法中都使用了 public 权限访问修饰符,表示它们都对外开放,对象使用者可以访问它们,如下:
Man man = new Man();
man.age = 32;
man.name = "张三“;
man.play();
private 访问修饰符
private 表示私有的,也就是隐藏,不对外公开
假如我们不想随便对外公开年龄、姓名和兴趣,那么就可以使用 private 将其隐藏起来,让对象使用者没有权限访问,如下:
public class Man {
private int age;
private String name;
private void play() {
System.out.println("喜欢打游戏");
}
}
还是用外部对象访问,如下:
Man man = new Man();
man.age = 32;
man.name = "张三“;
man.play();
看一看结果如何
C:\Users\xubin\Desktop\Java\MyProject\src\HelloWorld.java
Error:(9, 12) java: age 在 Man 中是 private 访问控制
Error:(10, 12) java: name 在 Man 中是 private 访问控制
Error:(11, 12) java: play() 在 Man 中是 private 访问控制
编译报错了,错误提示是 private 访问权限,外部对象禁止访问。
Getter 访问器与 Setter 修改器
Getter 访问器和 Setter 修改器是为 private 修饰的类成员变量提供安全访问的一种方式
public class Man {
private int age;
private String name;
public int getAge( ) { // Getter 访问器
return age;
}
public void setAge(int age) {// Setter 修改器
this.age = age;
}
}
使用 Getter 访问器与 Setter 修改器,如下:
Man man = new Man();
man.setAge(32);
System.out.println( man.getAge( ) );
Getter 访问器和 Setter 修改器的作用
-
可以为 private 修饰的属性(或成员变量)提供统 一的外界访问通道
-
可以为外界提供访问安全性(访问条件判断)
-
可以在访问器中设置访问权限控制或管理(实现按权限级别访问内部数据)
总结
在面向对象编程中,我们需要考虑哪些成员变量或方法需要对外公开,提供给对象使用者(也就是 public);哪些成员变量或方法需要隐藏细节,禁止对象使用者访问。
this 关键字
在 Java 中,this 关键字指的是当前对象的引用,它有 5 种用法
1、消除语法歧义(最常用)
这种情况一般出现在有参构造器中,当构造器的参数与类的属性(或成员变量)名称完全相同时,导致 Java 编译器无法区别,从而产生语法歧义,编译报错。
解决办法就是使用 this 关键字,如下代码:
public class Man {
private int age;
private String name;
public Man (int age, String name) {
this.age = age;
this.name = name;
}
}
Man 类有两个成员变量,分别是 age 和 name,在使用有参构造器的时候,如果参数名和成员变量的名字相同,就需要使用 this 关键字消除歧义。
其中 this.age 是指类的成员变量,age 是指有参构造器的参数。
2、引用类的其他构造器
当一个类的构造器有多个,可以使用 this 关键字在一个构造器内部调用其他构造器,从而减少代码量
比如说,在无参构造器中调用有参构造器,如下代码:
public class Man {
private int age;
private String name;
public Man(int age, String name) {
this.age = age;
this.name = name;
}
public Man() {
this(23, "张三"); //显示默认构造器调用有参构造器
}
}
也可以在有参构造器中调用无参构造器,如下代码:
public class Man {
private int age;
private String name;
public Man(int age, String name) {
this(); // 有参构造器内部调用显式默认构造器
this.age = age;
this.name = name;
}
public Man() {
}
}
需要注意的是,Java 语法要求 this() 必须是构造器方法体中的第一条语句,否则就会报错。不信,你可以自己试一试哈。
3、作为方法参数传递
先看下面的代码
public class Test {
public Test() {
print(this);
}
private void print(Test test) {
System.out.println("print 方法:" + test);
}
public static void main(String[] args) {
Test test = new Test();
System.out.println("main方法:“+test);
}
}
我在显式默认构造器中调用了 print( ) 方法,然后把 this 关键字作为参数传递给该方法,接着在 print( ) 方法中打印 this 关键字的值。在 程序入口 main() 方法中,实例化 Test 对象,然后同样打印对象名的值。
来打印看一下结果:
print方法: com.cmower.baeldung.this1.ThisTest@573fd745
main方法:com.cmower.baeldung.this1.ThisTest@573fd745
从结果中可以看得出来,this 关键字和 test 对象名都指向同一个对象的引用(或地址),而那个对象就是使用 new 关键字创建的 test 对象。
4、链式调用
学过 JavaScript,或者 jQuery 的读者可能对链式调用比较熟悉,类似于 a.b().c().d(),仿佛能无穷无尽调用下去。
在 Java 中,也可以使用 this 关键字编写链式调用,代码如下:
public class Man {
private int age;
private String name;
public Writer() {
}
public Man SetName(String name) {
this.name = name;
return this;
}
public Man SetAge(String age) {
this.age = age;
return this;
}
}
这时候,创建 Man 对象就可以通过链式调用的方式设置姓名和年龄
Man man = new Man();
man.setName("张三“).setAge(23);
5、在内部类中访问外部类对象
自从 Java 8 的函数式编程出现后,就很少用到 this 在内部类中访问外部类对象了
public class Test {
private String name;
class InnerClass {
public InnerClass() {
Test test = Test.this;
String name = test.name;
}
}
}
在内部类 InnerClass 的构造方法中,通过外部类.this 可以获取到外部类对象,然后就可以使用外部类的成员变量了,比如说 name。
总结
以上 5 种 this 关键字的使用没必要全部掌握,很多用法实际项目开发中很少或根本用不到,所以仅作了解而已即可。毕竟我们学 Java 是为了开发,应该关注使用最频繁的用法,如果花费太多精力去研究语言本身的各种稀奇古怪的用法,简直是本末倒置。
static 关键字
static 关键字可用于变量、方法、代码块,表示某个特定的成员只属于某个类本身,而不是该类的某个对象。
1、静态变量
静态变量也叫类变量,它属于一个类,而不是这个类的对象。
public class Man {
private String name;
private int age;
public static int num;
public Man(String name, int age) {
this.name = name;
this.age = age;
num++;
}
}
其中,num 被称为静态变量,它有别于 name 和 age 这两个成员变量,因为它前面多了一个修饰符 static。
这意味着无论这个类被实例化对象多少次,静态变量的值都会在所有实例化对象*享。
Man man = new Man("张三", 32);
Man man2 = new Man("李四",35);
System.out.println(Man.num);
打印结果 num 的值为2,而不是 1。
静态变量和成员变量有着很大的不同,成员变量的值属于某个对象,不同的对象之间,值是不共享的;但静态变量不是的,它可以用来统计对象的数量,因为它是共享的。就像上面例子中的 num,创建一个对象的时候,它的值为 1,创建两个对象的时候,它的值就为 2。
-
由于静态变量属于一个类,所以不能通过对象引用来访问,而应该直接通过类名来访问;
-
不需要初始化类就可以访问静态变量
2、静态方法
静态方法也叫类方法,它和静态变量类似,属于一个类,而不是这个类的对象
public static void setNum(int num) {
Man.num = num;
}
setNum() 就是一个静态方法,它由 static 关键字修饰
回忆一下,我们在这之间其实已经用了很多次静态方法,只是那时候不清楚而已。
总结
-
抽象方法不能是静态方法
-
静态方法不能使用 this 和 super 关键字
-
静态方法可以访问所有其他静态方法和静态变量
-
静态方法无法访问普通方法和成员变量
3、静态代码块
静态代码块可以用来初始化静态变量,尽管静态方法也可以在声明的时候直接初始化,但有些时候,我们需要多行代码来完成初始化。
public class man {
public static int age;
public static String name;
// 静态初始化块
static {
age = 32;
name = "张三“;
}
}
静态类成员的注意事项:
-
类的静态方法中不能调用非静态方法和非静态成员变量(也不能使用this和super)
-
类的非静态方法中可以调用静态方法和静态成员变量
Jar 包
jar 包 ( Java Archive,Java 归档文件) 是与平台无关的压缩文件格式,它允许将多个 class 文件组合成一个压缩文件(文件后缀名 *.jar)
Jar 包的作用
-
用于发布和使用第三方类库
-
作为应用程序和扩展的构建单元
-
作为组件、applet 或者插件程序的部署单位
-
用于打包和组件相关的辅助资源
Jar 包的生成
-
DOS 命令
jar 命令:用于将 class 文件打包成 jar 包
-
IDEA 生成和导入 Jar 包