在之前的文章我们介绍了一下 Java 类的重写及与重载的区别,本章我们来看一下 Java 类的 private,static,final。

我们在之前引入 Java 类概念的时候是通过商场收银台来引入的,如下:

如果我们使用刷卡的形式进行付账,我们需要出示一张有足够余额的银行卡或者会员卡来进行付款,在付款的时候我们仅仅是通过刷卡,输入密码来完成支付,在这个过程中,收银员是不能看到我们的卡号,密码,余额这些私密性的数据,否则可能会出现被盗刷或者其他问题,收银员在收银的时候只需要做的就是我们输入密码时对我们输入的密码与原始密码时候匹对和账户余额是否大于等于商品价格就可以了。

根据上面的分析我们我们可以定义一个 Card 类:

 class Card{
private String cartId; // 卡号
private String cardPwd; // 密码
private double balance; // 余额
public boolean payMoney(double money){ // 支付
if(balance >= money){
balance -= money;
return true;
}
return false; }
public boolean checkPwd(String pwd){ // 检查密码
if(cardPwd.equals(pwd)){
return true;
}
return false;
}
}

在上面的代码中,我们将变量前的修饰词写成了 private,将方法前的修饰词写成了 public。接下来我们看一下 private 和 public 之间的区别。

private 修饰从成员变量和方法只能在本类中调用,public 修饰的成员变量和方法可以在任何地方调用。

private 修饰的内容是对内实现的封装,public 修饰的内容是对外提供可以被调用的功能。

另外还有两种:protected 和 默认不写,我们称之为访问控制修饰符,他们的控制范围分别是:

1)public:公开的,任何类

2)private:私有的,本类

3)protected:受保护的,本类、子类、同包类

4)默认的(什么也不写):本类、同包类

接下来我们看一下关键字 static 。

之前我们在类中定义的变量其实可以叫做实例变量,还有一种变量叫做静态变量,即用 static 关键字修饰。我们先来看一下两种变量之间的区别:

1、实例变量:

 1)属于对象的,存在对重

 2)有几个对象就有几份实例变量

 3)必须通过 对象名. 来访问

2、静态变量:

 1)属于类的,存在方法区中

 2)只有一份

 3)必须通过 类名. 来访问

我们通过下面的代码来实际看一下:

 public class HelloWorld {
public static void main(String[] args) {
Aoo aoo1 = new Aoo();
aoo1.show(); // a=1 b=1 Aoo aoo2 = new Aoo();
aoo2.show(); // a=1 b=2
}
} class Aoo {
int a;
static int b; Aoo() {
a++;
b++;
} void show() {
System.out.println("a=" + a);
System.out.println("b=" + b);
}
}

在上面的代码中我们分别定义了实例变量a 和静态变量b,然后实例化了两次 Aoo,再通过两次调用实例化 Aoo 后调用 show() 方法可以看出我们实例化后调用的实例变量 a 的值不变,即每实例一次就会复制出一个 a,而静态变量 b 则每实例化一次后值会变化,即实例化后并不会重新复制一个 b,而是继续使用上一次的。

接下来我们看一下 static 关键字的静态方法。

静态方法和上面的静态变量大体上相同,但也有特殊的地方。

 1)属于类的,存在方法区中

 2)只有一份

 3)必须通过 类名. 来访问

 4)没有隐式的 this 传递,静态方法中不能直接访问实例变量

 class Aoo {
int a; // 实例变量---对象点访问
static int b; // 静态变量---类名点访问 void test1() { // 实例方法
a++;
b++;
} static void test2() { // 静态方法
a++; // 编译错误
test1(); // 编译错误
b++;
}
}

在上面的代码中,我们通过 static 关键字将变量 b 变为静态变量,将 test2() 变为静态方法,当我们在 test1() 的实例方法中 a++ 和 b++ 时,系统会默认为我们写成 this.a++ 和 Aoo.b++;而在 test2() 中,由于静态方法没有隐式 this,所以 a++ 和 test1() 方法并没有。

接下来我们看一下 static 关键字的静态块。

 public class HelloWorld {
public static void main(String[] args) {
Aoo aoo1 = new Aoo(); // 静态块 构造方法
Aoo aoo2 = new Aoo(); // 构造方法
}
} class Aoo {
static {
System.out.println("静态块");
} Aoo(){
System.out.println("构造方法");
}
}

在上面的代码中,我们在 Aoo 中创建了一个构造方法,并且通过  static { } 创建了一个静态块,我们实例化了两个 Aoo 类,我们发现静态块只加载一次,而静态方法每实例化一次就加载一次。

静态块在实际应用中可以加载图片,音频,视频等静态资源,比如我们逛淘宝时图片只加载一次,不可能每个人近义词淘宝网站就加载一次,服务器压力也受不了。

接下来我们来看一下 final 关键字。

1、final 修饰成员变量,两种方式初始化:

  1)声明的同事初始化

  2)构造方法中初始化

2、final 修饰局部变量,只要在用之前初始化即可。

代码如下:

 class Aoo {
int a = 10;
int b;
final int c = 10; // 声明同时初始化
// final int d; // 编译错误 声明未初始化
final int e; Aoo() {
e = 10; // 构造方法中初始化
} void test() {
final int f; // 局部变量:用之前赋值即可,不用刻意不用赋值
a = 20;
// c = 20; // 编译错误,final 修饰变量不能被改变
} }

final 修饰方法:final 修饰方法不能被重写。

代码如下:

 class Aoo {
void test(){}
final void show(){}
} class Boo extends Aoo{
void test(){}
void show(){} // 编译错误,final 方法不能被重写
}

final 修饰类:final 修饰的类不能被继承,但是能继承其他类

代码如下:

 class Aoo {}
class Boo extends Aoo{}
final class Coo extends Aoo{} // final 修饰的类可以继承别的类 final class Doo{}
class Eoo extends Doo{} // 编译错误,final 修饰的类不能被继承