实例变量与静态变量
本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 15 课,共 87 课。
到目前为止,我们创建的每个字段都属于特定对象。每个 BankAccount 都有自己的 balance,每个 Product 都有自己的 name。这些是实例变量,它们在类的每个实例中分别存在。
但如果你需要在所有对象之间共享数据,该怎么办?这时就要用到静态变量(也称为类变量)。静态变量属于类本身,而不属于任何特定对象。
public class Student {
private String name; // 实例变量:每个学生各有一个
private static int totalCount; // 静态变量:所有学生共享
public Student(String name) {
this.name = name;
totalCount++; // 将共享计数器加一
}
public static int getTotalCount() {
return totalCount;
}
}创建多个学生时,每个学生都有自己的 name,但他们共享同一个 totalCount:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // 输出:2注意,我们通过类名(Student.getTotalCount())而不是对象来访问静态变量。这强调了静态成员属于类,而不属于实例。
对于对象之间不同的数据(例如学生的姓名),使用实例变量。对于应该共享的数据(例如统计对象的数量),使用静态变量。
挑战
简单让我们使用实例变量和静态变量来构建一个 Book 库存系统,跟踪每本书的详细信息,以及整个藏书的书籍总数。
你将创建两个文件来组织代码:
Book.java:创建一个 Book 类,用于跟踪每本书的信息,同时统计创建过的所有书籍:- 实例变量
title(String),每本书各不相同 - 实例变量
price(double),每本书各不相同 - 静态变量
totalBooks(int),由所有 Book 对象共享,用于统计已创建的书籍数量 - 一个接收标题和价格的构造函数,并递增书籍总数
- 用于获取标题的 getter:
getTitle() - 用于获取价格的 getter:
getPrice() - 静态方法
getTotalBooks(),用于返回已创建的书籍总数
- 实例变量
Main.java:创建多个 Book 对象,并演示静态计数器如何跟踪所有实例。你将收到三本书的标题和三个价格作为输入。创建完这三本书后,打印四行:- 每本书的标题和价格,格式为:
[title]: $[price](价格格式化为小数点后 2 位) - 使用静态方法输出书籍总数:
Total books: [count]
- 每本书的标题和价格,格式为:
你将依次收到六个输入:title1、price1、title2、price2、title3、price3。
记得通过类名 Book.getTotalBooks() 调用静态方法,而不是通过对象实例调用。格式化价格时,请使用 String.format("%.2f", price)。
亲手试试
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取 3 本书的输入
String title1 = scanner.nextLine();
double price1 = Double.parseDouble(scanner.nextLine());
String title2 = scanner.nextLine();
double price2 = Double.parseDouble(scanner.nextLine());
String title3 = scanner.nextLine();
double price3 = Double.parseDouble(scanner.nextLine());
// TODO: 使用上面的输入创建 3 个 Book 对象
// TODO: 按以下格式输出每本书的书名和价格:[title]: $[price]
// 使用 String.format("%.2f", price) 将价格格式化为保留 2 位小数
// TODO: 使用静态方法输出书籍总数
// 格式:Total books: [count]
// 记得通过类名调用静态方法:Book.getTotalBooks()
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Java 在线编译器