Biến của instance và biến tĩnh
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 15 trên 87.
Đến nay, mọi trường dữ liệu chúng ta tạo đều thuộc về một đối tượng cụ thể. Mỗi BankAccount có balance riêng, và mỗi Product có name riêng. Đây là biến thực thể (instance variable), chúng tồn tại riêng biệt cho từng thực thể của một lớp.
Nhưng nếu bạn cần dữ liệu dùng chung cho tất cả đối tượng thì sao? Đây là lúc biến tĩnh (còn gọi là biến lớp) phát huy tác dụng. Biến tĩnh thuộc về chính lớp, không thuộc về một đối tượng cụ thể nào.
public class Student {
private String name; // Biến instance (instance variable): riêng cho từng sinh viên
private static int totalCount; // Biến tĩnh (static variable): dùng chung cho mọi sinh viên
public Student(String name) {
this.name = name;
totalCount++; // Tăng bộ đếm dùng chung
}
public static int getTotalCount() {
return totalCount;
}
}Khi bạn tạo nhiều học sinh, mỗi người có name riêng, nhưng tất cả đều dùng chung totalCount:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // Đầu ra: 2Hãy chú ý cách chúng ta truy cập biến tĩnh thông qua tên lớp (Student.getTotalCount()) thay vì thông qua đối tượng. Điều này nhấn mạnh rằng các thành viên tĩnh thuộc về lớp, không thuộc về các đối tượng.
Dùng biến thực thể cho dữ liệu khác nhau giữa các đối tượng, chẳng hạn như tên học sinh. Dùng biến tĩnh cho dữ liệu cần được chia sẻ, chẳng hạn như số lượng đối tượng hiện có.
Thử thách
DễHãy xây dựng hệ thống quản lý kho Book để theo dõi thông tin của từng cuốn sách và tổng số sách trong toàn bộ bộ sưu tập bằng biến thực thể và biến static.
Bạn sẽ tạo hai tệp để sắp xếp code:
Book.java: Tạo một lớp Book để theo dõi thông tin từng cuốn sách, đồng thời đếm tất cả sách đã tạo:- Một biến thực thể (instance variable)
title(String), riêng cho từng cuốn sách - Một biến thực thể
price(double), riêng cho từng cuốn sách - Một biến static
totalBooks(int), dùng chung cho mọi đối tượng Book, theo dõi số sách đã tạo - Một hàm khởi tạo nhận tiêu đề và giá, rồi tăng tổng số sách
- Một phương thức getter
getTitle()để lấy tiêu đề - Một phương thức getter
getPrice()để lấy giá - Một phương thức static
getTotalBooks()trả về tổng số sách đã tạo
- Một biến thực thể (instance variable)
Main.java: Tạo nhiều đối tượng Book và minh họa cách biến đếm static theo dõi mọi đối tượng. Bạn sẽ nhận ba tiêu đề sách và ba mức giá làm đầu vào. Sau khi tạo cả ba cuốn sách, hãy in ra bốn dòng:- Tiêu đề và giá của từng cuốn sách theo định dạng:
[title]: $[price](giá được định dạng với 2 chữ số thập phân) - Tổng số sách bằng phương thức static:
Total books: [count]
- Tiêu đề và giá của từng cuốn sách theo định dạng:
Bạn sẽ nhận sáu đầu vào theo thứ tự: title1, price1, title2, price2, title3, price3.
Hãy nhớ gọi phương thức static thông qua tên lớp (Book.getTotalBooks()) thay vì thông qua một đối tượng. Để định dạng giá, hãy dùng String.format("%.2f", price).
Tự làm thử
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Đọc dữ liệu đầu vào cho ba cuốn sách
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: Tạo ba đối tượng Book bằng dữ liệu đầu vào ở trên
// TODO: In ra tên và giá của từng cuốn sách theo định dạng: [title]: $[price]
// Dùng String.format("%.2f", price) để định dạng giá với 2 chữ số thập phân
// TODO: In ra tổng số sách bằng phương thức tĩnh
// Định dạng: Total books: [count]
// Nhớ gọi phương thức tĩnh qua tên lớp: Book.getTotalBooks()
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online