了解class成员
在本节中,我们讨论如何使用static
关键字来创建属于该类而不是该类实例的字段和方法。
Class Variables
当从同一类蓝图创建多个对象时,每个对象都有各自不同的实例变量副本。对于Bicycle
类,实例变量是cadence
,gear
和speed
。每个Bicycle
对象对于这些变量都有其自己的值,存储在不同的存储位置中。
有时,您希望拥有所有对象共有的变量。这是通过static
修饰符完成的。声明中带有static
修饰符的字段称为静态字段或类变量。它们与类关联,而不与任何对象关联。该类的每个实例共享一个类变量,该变量位于内存中的一个固定位置。任何对象都可以更改类变量的值,但是也可以在不创建类实例的情况下操纵类变量。
例如,假设您要创建多个Bicycle
对象,并为每个对象分配一个序列号,第一个对象以 1 开头。该 ID 号对于每个对象都是唯一的,因此是一个实例变量。同时,您需要一个字段来跟踪已创建的Bicycle
个对象,以便知道要分配给下一个对象的 ID。这样的字段与任何单个对象都不相关,而与整个类有关。为此,您需要一个类变量numberOfBicycles
,如下所示:
public class Bicycle {
private int cadence;
private int gear;
private int speed;
// add an instance variable for the object ID
private int id;
// add a class variable for the
// number of Bicycle objects instantiated
private static int numberOfBicycles = 0;
...
}
类变量由类名本身引用,如
Bicycle.numberOfBicycles
这清楚表明它们是类变量。
Note:
您还可以使用对象引用来引用静态字段,例如
myBike.numberOfBicycles
但是不建议这样做,因为它并不能清楚地表明它们是类变量。
您可以使用Bicycle
构造函数来设置id
实例变量并增加numberOfBicycles
类变量:
public class Bicycle {
private int cadence;
private int gear;
private int speed;
private int id;
private static int numberOfBicycles = 0;
public Bicycle(int startCadence, int startSpeed, int startGear){
gear = startGear;
cadence = startCadence;
speed = startSpeed;
// increment number of Bicycles
// and assign ID number
id = ++numberOfBicycles;
}
// new method to return the ID instance variable
public int getID() {
return id;
}
...
}
Class Methods
Java 编程语言支持静态方法以及静态变量。静态方法的声明中带有static
修饰符,应使用类名来调用,而无需创建该类的实例,如
ClassName.methodName(args)
Note:
您还可以使用对象引用来引用静态方法,例如
instanceName.methodName(args)
但这是不鼓励的,因为并不能清楚地表明它们是类方法。
静态方法的常见用法是访问静态字段。例如,我们可以向Bicycle
类添加静态方法以访问numberOfBicycles
静态字段:
public static int getNumberOfBicycles() {
return numberOfBicycles;
}
并非允许实例和类变量以及方法的所有组合:
-
实例方法可以直接访问实例变量和实例方法。
-
实例方法可以直接访问类变量和类方法。
-
类方法可以直接访问类变量和类方法。
-
类方法不能直接访问实例变量或实例方法,它们必须使用对象引用。另外,类方法不能使用
this
关键字,因为没有可供this
引用的实例。
Constants
static
修饰符与final
修饰符一起还用于定义常量。 final
修饰符表示此字段的值不能更改。
例如,以下变量声明定义了一个名为PI
的常量,其值近似为 pi(圆的周 Long 与其直径之比):
static final double PI = 3.141592653589793;
不能重新分配以这种方式定义的常量,如果您的程序try这样做,则是编译时错误。按照约定,常量值的名称用大写字母拼写。如果名称由多个单词组成,则单词之间用下划线(_)分隔。
Note:
如果将原始类型或字符串 定义为常量,并且在编译时知道该值,则编译器会将代码中所有位置的常量名称替换为其值。这称为编译时常量。如果外界的常数值发生了变化(例如,如果 pi 实际应为 3.975,则需要立法),则需要重新编译使用该常数的任何类以获取当前值。
自行车课
完成本节中的所有修改后,Bicycle
类现在为:
public class Bicycle {
private int cadence;
private int gear;
private int speed;
private int id;
private static int numberOfBicycles = 0;
public Bicycle(int startCadence,
int startSpeed,
int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
id = ++numberOfBicycles;
}
public int getID() {
return id;
}
public static int getNumberOfBicycles() {
return numberOfBicycles;
}
public int getCadence() {
return cadence;
}
public void setCadence(int newValue) {
cadence = newValue;
}
public int getGear(){
return gear;
}
public void setGear(int newValue) {
gear = newValue;
}
public int getSpeed() {
return speed;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}