1. Giới thiệu
Khi bạn mới bắt đầu lập trình, có vẻ như chỉ cần viết mã từng dòng là mọi thứ sẽ chạy. Nhưng ngay khi chương trình phức tạp hơn, bạn sẽ bắt đầu rối: cái gì ở đâu, viết để làm gì, và nếu cần sửa một dòng — thì nó nằm ở chỗ nào?
Vì vậy Java, cũng như hầu hết các ngôn ngữ hiện đại, cung cấp cách “sắp xếp” mã vào từng ngăn, để bất cứ lúc nào bạn cũng có thể hiểu chương trình làm gì và nhanh chóng tìm đúng chỗ cần sửa.
Hãy tưởng tượng một công ty. Có phòng nhân sự, kế toán, phòng IT, phòng logistics, v.v. Mỗi phòng — có phạm vi trách nhiệm, nhân sự và nhiệm vụ riêng.
Trong chương trình Java, mỗi “phòng ban” như vậy — là một lớp. Một lớp, chẳng hạn, chịu trách nhiệm làm việc với người dùng, lớp khác — cho tính toán, lớp thứ ba — cho làm việc với tệp.
Đây là cấu trúc điển hình của một dự án đơn giản:
- Main.java — trụ sở chính: ở đây có “điểm vào” nơi mọi thứ bắt đầu.
- User.java — “phòng” lưu trữ và xử lý dữ liệu người dùng.
- Calculator.java — “phòng” tính toán.
- FileHelper.java — “chuyên gia” về tệp.
Ngay cả trong một chương trình rất nhỏ thường cũng có ít nhất một lớp. Còn các dự án lớn — là cả một “tòa nhà chọc trời” với hàng trăm lớp!
2. Lớp — là hộp đựng dụng cụ
Java là một ngôn ngữ lập trình hướng đối tượng, và mọi thứ trong đó đều là đối tượng. Kiểu của đối tượng được gọi là lớp.
Lớp giống như một chiếc hộp hay ngăn tủ, nơi ta đặt những thứ cần thiết: biến, phương thức. Hãy tưởng tượng một hộp có nhãn “Búa”: bên trong chỉ có các dụng cụ liên quan đến búa.
class Example
{
// Ở đây là các công cụ của chúng ta: biến và phương thức
}
Các lớp thường chứa biến và hàm. Trong Java, biến của lớp thường được gọi là trường (fields), còn hàm của lớp — là phương thức. Nhưng ý nghĩa không thay đổi.
Nhớ đoạn mã đầu tiên của chúng ta chứ?
System.out.println("Xin chào mọi người!");
Trong đoạn mã này có cả lớp và phương thức:
- System — là lớp chứa các phương thức làm việc với hệ thống.
- out — là trường, là một đối tượng của lớp PrintStream.
- println — là phương thức của lớp PrintStream, dùng để in văn bản ra màn hình.
Ở một khía cạnh nào đó, lập trình là viết các lớp và phương thức của riêng bạn, rồi gọi các phương thức của những lớp khác.
3. Cách viết rút gọn phương thức main()
Thực ra, chương trình tối thiểu trong Java trông như sau:
class Program
{
public static void main(String[] args)
{
// Mã của bạn ở đây
}
}
Nó chứa tối thiểu một lớp, lớp đó phải có phương thức main với phần đầu (chữ ký) như sau:
public static void main(String[] args)
main trong Java
Tuy nhiên trong Java 21 đã xuất hiện khả năng viết phương thức main() theo dạng rút gọn. Trình biên dịch Java sau đó (khi biên dịch) sẽ chuyển nó thành phương thức main() đúng chuẩn.
Vì thế mỗi lần bạn viết đoạn mã kiểu:
void main()
{
Scanner console = new Scanner(System.in);
int age = console.nextInt();
System.out.println("Tuổi: " + age);
}
Trình biên dịch Java sẽ chuyển nó thành mã:
class Program
{
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
int age = console.nextInt();
System.out.println("Tuổi: " + age);
}
}
4. Một lớp Java điển hình
Một lớp Java điển hình trông như thế này:
public class MathUtils
{
// Biến static (toàn cục cho lớp)
static final double PI = 3.14159;
static int callCounter = 0;
// Phương thức static: tính diện tích hình tròn
public static double circleArea(double radius)
{
callCounter++;
return PI * radius * radius;
}
// Phương thức static: tìm giá trị lớn nhất của hai số
public static int max(int a, int b)
{
callCounter++;
return (a > b) ? a : b;
}
// Phương thức static: số lần các phương thức đã được gọi
public static int getCallCount()
{
return callCounter;
}
// Truy cập vào các trường và phương thức từ phương thức main()
public static void main(String[] args)
{
System.out.println("Diện tích hình tròn: " + circleArea(5));
System.out.println("Giá trị lớn nhất: " + max(10, 42));
System.out.println("Các phương thức đã được gọi " + getCallCount() + " lần");
}
}
Chúng ta thấy gì ở đây:
- Một lớp có thể có nhiều phương thức.
- Một lớp có thể có các biến riêng.
- Các phương thức của lớp có thể gọi lẫn nhau.
- Các phương thức của lớp có thể truy cập các biến dùng chung.
- Trước mỗi phương thức đều có các “từ khóa” giống nhau như: public static.
- Trước mỗi phương thức là các kiểu khác nhau: int, double, void.
Bên dưới chúng ta sẽ phân tích tất cả các chi tiết này.
5. Trường (biến) của lớp — là bộ nhớ của nó
Bên trong lớp có thể lưu trữ các biến, thường được gọi là trường (fields). Chúng như những ô nhớ, nơi ta đặt dữ liệu nào đó.
public class MathUtils
{
// Biến static (toàn cục cho lớp)
static final double PI = 3.14159;
static int callCounter = 0;
}
Các trường cho phép lớp “ghi nhớ” điều gì đó giữa các lần gọi phương thức khác nhau. Ví dụ, đếm bao nhiêu lần nhấn nút. Hoặc bao nhiêu lần một phương thức đã được gọi (callCounter). Số lượng trường có thể tùy ý.
6. Phương thức — các hành động mà lớp có thể thực hiện
Phương thức — là “kỹ năng” của lớp. Nếu lớp là một nhân viên, thì phương thức là các kỹ năng của anh ta: anh ta có thể làm gì.
Ví dụ, một phương thức có thể:
- in ra màn hình,
- tính tổng của hai số,
- nhận dữ liệu “đầu vào” và trả về kết quả.
Cấu trúc của phương thức:
- Kiểu giá trị trả về (ví dụ, void — nếu không trả về gì, hoặc int — nếu trả về một số).
- Tên phương thức (ví dụ, circleArea).
- Tham số trong ngoặc (có thể không có).
- Dấu ngoặc nhọn { ... } — thân phương thức.
public class MathUtils
{
// Phương thức static: tính diện tích hình tròn
public static double circleArea(double radius)
{
callCounter++;
return PI * radius * radius;
}
// Phương thức static: tìm giá trị lớn nhất của hai số
public static int max(int a, int b)
{
callCounter++;
return (a > b) ? a : b;
}
}
Bạn sẽ biết chi tiết hơn về phương thức và các sắc thái liên quan trong những bài giảng sắp tới.
7. Bộ sửa đổi truy cập
Trong Java, ta có thể xác định phần nào của lớp được phép truy cập từ các lớp khác, phần nào chỉ dùng nội bộ. Để làm điều này sử dụng các bộ sửa đổi truy cập.
- public — ai cũng nhìn thấy. Các phương thức và trường như vậy có thể được dùng/gọi từ bất kỳ đâu trong chương trình.
- private — chỉ thấy bên trong chính lớp đó. Đây là các chi tiết nội bộ không nên cho bên ngoài truy cập. Như thể chúng không tồn tại vậy.
public class MathUtils
{
// Biến static (toàn cục cho lớp)
private static final double PI = 3.14159;
private static int callCounter = 0;
// Phương thức static: tính diện tích hình tròn
public static double circleArea(double radius)
{
callCounter++;
return PI * radius * radius;
}
}
Quy tắc vàng: các trường thường để private, còn chỉ “đưa ra ngoài” những phương thức cần thiết với bộ sửa đổi public. Chi tiết hơn về phạm vi truy cập — trong các bài giảng sắp tới.
8. Phương thức và biến static
Thông thường trong Java, lớp được dùng như một khuôn mẫu để tạo đối tượng. Bạn viết lớp, sau đó tạo các đối tượng của lớp bằng từ khóa new. Và chỉ sau đó mới gọi phương thức trên đối tượng.
Tuy nhiên còn có cách dùng thứ hai của lớp — như một “container” cho các biến và phương thức toàn cục có thể gọi từ bất cứ đâu trong chương trình. Chính cho mục đích này mà có từ khóa static. Nó nói với trình biên dịch Java rằng các phương thức và trường của lớp gắn với chính lớp, không phải với đối tượng của lớp. Vì thế có thể gọi chúng mà không cần tạo đối tượng.
Bạn, thực ra, dùng những phương thức như vậy thường xuyên:
Integer.parseInt(); // Phương thức static parseInt() của lớp Integer
String.valueOf(); // Phương thức static valueOf() của lớp String
Double.isInfinite(); // Phương thức static isInfinite() của lớp Double
Arrays.copy(); // Phương thức static copy() của lớp Arrays
Phương thức main() luôn được khai báo là static, vì từ đó chương trình Java của bạn bắt đầu chạy. Trước khi tạo bất kỳ đối tượng nào.
9. Mẹo trong IDEA
Chữ ký đầy đủ của phương thức main() như sau:
public static void main(String[] args)
Và để không phải viết nó mỗi lần trong IntelliJ IDEA, đã có phím tắt. Chỉ cần gõ psvm và nhấn Tab, IntelliJ IDEA sẽ tự động viết giúp bạn đoạn mã sau:
public static void main(String[] args)
{
}
Rất dễ nhớ — psvm — là chữ cái đầu của public static void main.
GO TO FULL VERSION