了解class成员

在本节中,我们讨论如何使用static关键字来创建属于该类而不是该类实例的字段和方法。

Class Variables

当从同一类蓝图创建多个对象时,每个对象都有各自不同的实例变量副本。对于Bicycle类,实例变量是cadencegearspeed。每个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;
    }
}