7.3 访问权限
一个商业的Java应用系统有很多类,其中有些类并不希望被其他类使用。每个类中都有属性和方法,但是并不是所有的属性和方法都允许被其他类调用。
Java语言中的访问权限修饰符有4种,但却只有3个关键字。因为不写访问权限修饰符时,在Java中被称为默认权限(包权限),以default代替。其他3个访问权限修饰符分别为private、protected 和 public。
对类的访问控制
对于类而言,能使用的访问权限修饰符只有public和default。如果使用public修饰,则表示该类在任何地方都能被访问,如果不写访问权限修饰符,则该类只能在本包中使用。
对类成员的访问控制
对于类的成员(属性和方法)而言,4种访问权限修饰符都可以使用。下面按照权限从小到大的顺序对四种访问权限修饰符分别进行介绍。
1.私有权限private
Private可以修饰属性、构造方法、普通方法。被private修饰的类成员只能在定义它们的类中使用,在其他类中不能访问。
封装的时候,已经使用了private这个私有的访问权限修饰符。对于封装良好的程序而言,一般将属性私有化,提供公有的getter和setter方法,供其他类调用。
构造方法私有化,就是说使用private修饰这个类的构造方法。
public class Student {
String stuName;//学生姓名
//构造方法私有化
private Student(String name){
this.stuName = name;
System.out.println("学生姓名为:" + this.stuName);
}
}
2.默认权限default
属性、构造方法、普通方法都能使用默认权限,即不写任何关键字。默认权限也称为同包权限。同包权限的元素只能在定义它们的类中以及同包的类中被调用。
3.受保护权限protected
protected可修饰属性、构造方法、普通方法,能在定义它们的类中以及同包的类中调用被protected修饰的成员。如果有不同包中的类想调用它们,那么这个类必须是这些成员所属类的子类。
4.公共权限public
Public可以修饰属性、构造方法和普通方法。被public修饰的成员,可以在任何一个类中被调用,是权限最大的访问权限修饰符。
修饰符 | 类内部 | 同一个包中 | 子类 | 任何地方 |
---|---|---|---|---|
private | Yes | |||
default | Yes | Yes | ||
protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
7.4 static关键字
在通常情况下,要使用一个类对象(实例)的公有成员变量,需要通过这个类实例化出对象,再通过“对象名.变量名”的形式访问。作为程序员,有时需要定义一个类级别的变量,它的使用完全独立于该类的任何对象,可以直接通过“类名.变量名”的形式进行访问。
在类成员的声明前,加上static(静态的)关键字,就能创建出这样的静态类成员。static成员最常见的例子是main方法。因为在程序开始执行时必须调用main方法,所以将它声明为static。
声明为static的变量称为静态变量或类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量,但最好采用前者,因为采用后者容易混淆静态变量和实例变量。静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量。
声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。
static关键字的使用
1.用static修饰类的成员变量
用static修饰的类的成员变量是静态变量,对该类的所有实例来说,只有一个静态值存在,所有实例共用一个变量。静态变量是指不管类实例化出多少个对象,系统仅在第一次调用类的时候为静态变量分配内存。
public class TestStatic{
public static void main(String[] args) {
Student wangYun = new Student();
wangYun.avgAge = 22; //将Student类变量的值设置为22
System.out.println("王云所在班平均年龄为:" + wangYun.avgAge);//22
Student liuJT = new Student();
liuJT.avgAge = 21; //将Student类变量的值设置为21
System.out.println("王云所在班平均年龄为:" + wangYun.avgAge);//21
System.out.println("刘静涛所在班平均年龄为:" + liuJT.avgAge);//21
}
}
class Student {
public static int avgAge; //类变量,存放平均年龄
}
所有Sutdent类的实例wangYun和liuJT都共用了静态变量avgAge,当给其中任何一个实例的静态变量赋值,都是对这一个静态变量进行操作。
2.用static修饰类的成员方法
用static修饰类的成员方法表示,该方法被绑定于类本身,而不是类的实例。
public class TestStatic2{
public static void main(String[] args) {
Student.showAvgAge(); //调用静态方法
System.out.println("静态变量输出所在班平均年龄为:" + Student.avgAge);
}
}
class Student {
public static int avgAge = 22;//类变量,存放平均年龄
public static void showAvgAge(){ //静态方法输出班平均年龄
System.out.println("静态方法输出所在班平均年龄为:22");
}
}
在TestStatic2程序的main方法中,都是通过“类名.静态变量名”和“类名.静态方法名”的形式访问静态变量和调用静态方法的。通过“类实例.静态变量”和“类实例.静态方法”也可以访问静态变量和调用静态方法,但不推荐使用。
3.静态方法不能操作实例变量
静态方法可以操作静态变量,不能操作实例变量。
Java静态块
对象的初始化过程,在使用 new 关键字创建并初始化对象的过程中,具体的初始化分为以下4步。
-
给对象的实例变量分配空间,默认初始化成员变量。
-
成员变量声明时的初始化。
-
初始化块初始化。
-
构造方法初始化。
静态块的语法形式如下。
static{
//语句块
}
Java类首次装入JVM时,会对静态变量(含静态块)或方法进行一次初始化,方法不被调用是不会执行的,就是说静态变量和静态块是在类首次装载进JVM时被执行的。
静态变量和静态块都是在类实例化对象前被执行的。