Giao diện hàm
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 39 trên 87.
Giao diện hàm (functional interface) là giao diện chỉ chứa đúng một phương thức trừu tượng. Quy tắc chỉ có một phương thức này khiến giao diện hàm trở nên đặc biệt, vì bạn có thể triển khai chúng bằng biểu thức lambda, giúp viết code ngắn gọn hơn.
Java cung cấp chú thích @FunctionalInterface để đánh dấu rõ ràng một giao diện là giao diện hàm. Dù không bắt buộc, chú thích này giúp trình biên dịch phát hiện lỗi nếu bạn vô tình thêm một phương thức trừu tượng thứ hai:
@FunctionalInterface
public interface Calculator {
int calculate(int a, int b);
}Bạn có thể triển khai giao diện hàm (functional interface) theo cách truyền thống bằng một lớp, hoặc viết ngắn gọn hơn bằng biểu thức lambda:
// Cách triển khai truyền thống
Calculator adder = new Calculator() {
@Override
public int calculate(int a, int b) {
return a + b;
}
};
// Biểu thức lambda (ngắn hơn nhiều!)
Calculator adder = (a, b) -> a + b;
System.out.println(adder.calculate(5, 3)); // 8Giao diện hàm vẫn có thể có phương thức mặc định và phương thức tĩnh vì chúng không được tính vào quy tắc chỉ có một phương thức trừu tượng. Gói java.util.function của Java cung cấp nhiều giao diện hàm dựng sẵn như Predicate, Function và Consumer. Bạn sẽ thường gặp chúng khi làm việc với luồng và bộ sưu tập.
Thử thách
DễHãy xây dựng một hệ thống chuyển đổi chuỗi bằng giao diện hàm (functional interface) và biểu thức lambda. Bạn sẽ tạo một bộ xử lý văn bản linh hoạt có thể áp dụng nhiều cách chuyển đổi khác nhau cho chuỗi, tất cả đều dựa trên một giao diện hàm duy nhất.
Bạn sẽ sắp xếp code trong ba tệp:
StringTransformer.java: Định nghĩa một giao diện hàm đại diện cho bất kỳ thao tác chuyển đổi chuỗi nào. Đánh dấu giao diện bằng chú thích@FunctionalInterfaceđể đảm bảo giao diện vẫn là giao diện hàm. Giao diện cần khai báo một phương thức trừu tượng duy nhất có têntransform, nhận một String và trả về một String.TextProcessor.java: Tạo một lớp dùng giao diện hàm của bạn để xử lý văn bản. Lớp cần có một trường lưuStringTransformervà một hàm khởi tạo để khởi tạo trường đó. Thêm phương thức có tênprocess(String text), áp dụng bộ chuyển đổi cho văn bản đã cho và trả về kết quả. Thiết kế này cho phép bạn truyền vào bất kỳ hành vi chuyển đổi nào thông qua hàm khởi tạo.Main.java: Kết hợp mọi thứ bằng cách tạo các cách chuyển đổi khác nhau với biểu thức lambda. Bạn sẽ nhận hai đầu vào: một chuỗi văn bản và một kiểu thao tác (upper,lowerhoặcreverse).Dựa trên kiểu thao tác, hãy tạo một
TextProcessorvới biểu thức lambda phù hợp:upper: chuyển văn bản thành chữ hoalower: chuyển văn bản thành chữ thườngreverse: đảo ngược văn bản (gợi ý: dùngStringBuilder)
Sau đó, gọi
process()với văn bản đầu vào và in kết quả theo định dạng này:Result: [transformed text]
Bạn sẽ nhận hai đầu vào: văn bản cần chuyển đổi (String) và kiểu thao tác (String).
Hãy chú ý cách cùng một lớp TextProcessor có thể thực hiện những thao tác hoàn toàn khác nhau tùy theo biểu thức lambda bạn truyền vào. Đó chính là sức mạnh của giao diện hàm!
Tự làm thử
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String text = scanner.nextLine();
String operation = scanner.nextLine();
TextProcessor processor;
// TODO: Dựa vào loại thao tác, tạo TextProcessor với lambda phù hợp:
// - "upper": chuyển văn bản thành chữ hoa
// - "lower": chuyển văn bản thành chữ thường
// - "reverse": đảo ngược văn bản (gợi ý: dùng StringBuilder)
// TODO: Gọi process() với văn bản đầu vào và in ra kết quả
// Định dạng đầu ra: "Result: [transformed text]"
}
}
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