10、Java基础---类变量

类变量

一、类变量(静态字段)

之前介绍的字段,即实例变量, 都是属于类的各个实例的数据;本节将介绍表示同一个类的实例之间共享数据的静态字段,即类变量。给之前的“银行账户类” 的各个实例中添加一个“标识编号” ,每创建一个实例,例,就为其赋上1, 2, 3 ... 的连续整数值。创建实例后,aaa的标识编号为1,bbb的标识编号为2.。

// A的账户
Account aaa = new Account("a", "123456", 1000);

// B的账户
Account bbb = new Account("b", "654321",  200);	

为了实现这个操作,类Account中需要添加一个标识编号字段字段类型为int型,名称为id,但仅此还不够,还需要数据:

当前已经赋到了哪—个标识编号;

这个数据既不属于aaa,也不属于bbb, 它不是属于各个实例的数据,而是类Account所有实例共享的数据
只要在字段声明时加上static, 就可以实现该数据;由于是类中共享的变量,因此被称为类变量,由于在声明时加上了static, 因此也被称为静态字段。

private static int counter = 0;		// 赋到了哪一个标识编号
	private String name;		// 账户名
	private String no;			// 账号
	private long balance;		// 可用余额
	private int id;				// 标识编号

类变量counter----当前赋到了哪一个标识编号:

声明中加上static的类变量counter表示当前赋到了哪一个标识编号。在使用类Account类型的程序中,无论创建了多少个Account类型的实例(即便一个实例也未创建),属于该类的类变量(静态字段)的主体都只会创建一个。

实例变量id---各个实例的标识编号:
声明中未加static的id表示各个实例的标识编号,不是静态的字段(非静态字段)的主体是各个实例的一部分,因此被称为实例变量。

Account.java

public class Account {
    private static int counter = 0;		// 赋到了哪一个标识编号[类变量]
    private String name;		// 账户名[实例变量]
    private String no;			// 账号[实例变量]
    private long balance;		// 可用余额[实例变量]
    private int id;				// 标识编号[实例变量]
    //-- 构造函数 --//
    public Account(String n, String num, long z) {
        name = n;				// 账户名
        no = num;				// 账号
        balance = z;			// 可用余额
        id = ++counter;			// 标识编号
    }
    //--- 确认账户名 ---//
    public String getName() {
        return name;
    }
    //--- 确认账号 ---//
    public String getNo() {
        return no;
    }
    //--- 确认可用余额 ---//
    public long getBalance() {
        return balance;
    }
    //--- 获取标识编号 ---//
    public int getId() {
        return id;
    }
    //--- 存入k日元 ---//
    public void deposit(long k) {
        balance += k;
    }
    //--- 取出k日元 ---//
    public void withdraw(long k) {
        balance -= k;
    }
}

代码讲解:

private static int counter = 0;		// 赋到了哪一个标识编号[类变量]

上述代码是全部账户(所有Account类型的实例)共享的类变量counter的声明。
如果能够从外部改写它的值,那么就无法正确地为实例赋上连续编号了,因此我们将其声明为私有字段【其初始值为0】

 private int id;				// 标识编号[实例变量]

上述代码是各个账户(各个Account类型的实例)持有的实例变量id的声明,我们使用构造函数来设置它们的值

id = ++counter;			// 标识编号

当使用构造函数初始化实例时,程序流程会通过上述代码,通过将变量counter递增后的值赋给标识编号id, 各个实例就被赋上了不同的标识编号

//--- 获取标识编号 ---//
    public int getId() {
        return id;
    }

上述代码是标识编号id的getter方法,通过调用该方法可以确认实例的标识编号

AccountTester.java

class AccountTester {
    public static void main(String[] args) {
        // A的账户
        Account aaa = new Account("a", "123456", 1000);
        // B的账户
        Account bbb = new Account("b", "654321",  200);
        System.out.println("■a的账户");
        System.out.println(" 账户名:" + aaa.getName());
        System.out.println(" 账号:" + aaa.getNo());
        System.out.println(" 可用余额:" + aaa.getBalance());
        System.out.println(" 标识编号:" + aaa.getId());
        System.out.println("■b的账户");
        System.out.println(" 账户名:" + bbb.getName());
        System.out.println(" 账号:" + bbb.getNo());
        System.out.println(" 可用余额:" + bbb.getBalance());
        System.out.println(" 标识编号:" + bbb.getId());
    }
}

输出:

类变量counter的值不一定和Account类型实例的个数相等,因为构建的实例有可能会在程序中间被销毁。
因此,不可以使用类变量来保存类类型的全部实例的个数。

二、类变量的访问

类变量不属于各个实例,而是属于类;因此,类变量通过下述表达式进行访问:

类名 . 字段名

不过无法从外部访问私有的银行账户类的counter,下面创建一个类,将Account类中标识编号以外的字段和方法都删除,来进行验证

class Id {
	static int counter = 0;		// 赋到了哪一个标识编号
	private int id;				// 标识编号
	//-- 构造函数 --//
	public Id() {
		id = ++counter;			// 标识编号
	}
	//--- 获取标识编号 ---//
	public int getId() {
		return id;
	}
}
public class IdTester {
	public static void main(String[] args) {
		Id a = new Id();		// 标识编号1号
		Id b = new Id();		// 标识编号2号
		System.out.println("a的标识编号:" + a.getId());
		System.out.println("b的标识编号:" + b.getId());
		System.out.println("Id.counter = " + Id.counter);
		System.out.println("a.counter  = " +  a.counter);
		System.out.println("b.counter  = " +  b.counter);
	}
}

输出:

类变量counter:

类变量counter本来是私有的,但在本试验程序中,其声明中并未加上private, 对外部是公开的。

实例变量id:
实例变量id是类Id的各个实例所持有的字段。它的值按创建顺序依次为1、2、3·····与银行账户类相同。

System.out.println("Id.counter = " + Id.counter);

上述代码使用了Id.counter表达式来访问类变量counter

System.out.println("a.counter  = " +  a.counter);
System.out.println("b.counter  = " +  b.counter);

也可以使用a.counter和b.counter 来访问该变量;也就是说,类变量也可以通过下述表达式进行访问

类类型变量名.字段名

因为“大家的counter" 既可以是"a 的counter" 也可以是"b的counter",所以这样的表达式是允许的。
不过,不建议使用容易让人混淆的形式,推荐使用  类名 . 字段名

三、库中提供的类变量

Java的库中也定义了各种类变量

Math类

Math 类中定义了自然对数的底数E 和圆周率PI 的类变量,它们都是double型的常量, 声明中都加上了final。

// java.lang.Math类的摘录

public final class Math {
	// 最接近自然对数的底数e的double值
	public static final double E = 2.7182818284590452354;

	// 最接近圆周和其直径比π的double值
	public static final double PI = 3.14159265358979323846;

	// ...
}

计算圆的周长和面积:

// 计算圆的周长和面积(使用圆周率Math.PI)

import java.util.Scanner;

class Circle {

	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);
		System.out.print("半径:");
		double r = stdIn.nextDouble();	// r中读入实数值
		System.out.println("周长是" + 2 * Math.PI * r + "。");
		System.out.println("面积是" + Math.PI * r * r + "。");
	}
}

输出:

Math.PI的值3.14159265358979323846是double型所能表示的最准确的圆周率,因此, 在double型所能表示的范围之内,能够以最小的误差计算圆的周长和面积。

如果常量需要提供给类的使用者,以public且final的类变量形式进行提供

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值