Interface trong Java: Hợp đồng của Gen Z Lập Trình!
Java – OOP

Interface trong Java: Hợp đồng của Gen Z Lập Trình!

Author

Admin System

@root

Ngày xuất bản

18 Mar, 2026

Lượt xem

1 Lượt

Interface

Chào các "coder nhí" tương lai, Creyt đây! Hôm nay chúng ta sẽ "đập hộp" một khái niệm nghe thì hàn lâm nhưng lại cực kỳ thực tế và "cool ngầu" trong thế giới Java OOP: Interface.

1. Interface là gì mà nghe "chiến" vậy?

Để dễ hình dung, các bạn Gen Z cứ tưởng tượng thế này: Interface trong Java nó giống như một bản Hợp đồng Lao động hoặc một Bản quy định chuẩn mực vậy. Nó không nói bạn phải làm công việc đó như thế nào, mà chỉ quy định bạn phải có khả năng làm những gì.

Hay cụ thể hơn, nó là một "khuôn mẫu" chỉ chứa các phương thức trừu tượng (abstract methods) – tức là những phương thức chỉ có chữ ký (tên, tham số, kiểu trả về) mà không có phần thân (không có code bên trong). Ngoài ra, nó có thể chứa các hằng số (public static final), các phương thức defaultstatic (từ Java 8 trở đi), hoặc phương thức private (từ Java 9).

Để làm gì ư? Đơn giản là để định nghĩa một tập hợp các hành vi mà bất kỳ lớp nào muốn "kết nối" hoặc "tuân thủ" cái Interface đó đều phải thực hiện. Nó giống như một lời cam kết: "Nếu bạn muốn được gọi là 'có thể bay được', bạn phải có phương thức bay()hạCánh()!"

2. "Show me the code!" – Ví dụ minh họa

Giả sử chúng ta muốn tạo các đối tượng có khả năng di chuyển. Chúng ta sẽ định nghĩa một Interface DiChuyenDuoc:

// Bước 1: Định nghĩa Interface - Bản hợp đồng quy định hành vi
interface DiChuyenDuoc {
    void diChuyen(String huong);
    void dungLai();
    
    // Từ Java 8, có thể có phương thức default
    default void thongBaoTocDo(int tocDo) {
        System.out.println("Tốc độ hiện tại: " + tocDo + " km/h");
    }
}

// Bước 2: Tạo các lớp thực thi Interface này - Các đối tượng tuân thủ hợp đồng
class XeOto implements DiChuyenDuoc {
    @Override
    public void diChuyen(String huong) {
        System.out.println("Xe ô tô đang lăn bánh về phía " + huong + ".");
    }

    @Override
    public void dungLai() {
        System.out.println("Xe ô tô đã dừng lại.");
    }
}

class MayBay implements DiChuyenDuoc {
    @Override
    public void diChuyen(String huong) {
        System.out.println("Máy bay đang cất cánh và bay về " + huong + ".");
    }

    @Override
    public void dungLai() {
        System.out.println("Máy bay đã hạ cánh an toàn.");
    }
}

class ConNguoi implements DiChuyenDuoc {
    @Override
    public void diChuyen(String huong) {
        System.out.println("Con người đang đi bộ về " + huong + ".");
    }

    @Override
    public void dungLai() {
        System.out.println("Con người đã đứng lại.");
    }
    
    // Có thể ghi đè phương thức default nếu muốn thay đổi hành vi
    @Override
    public void thongBaoTocDo(int tocDo) {
        System.out.println("Tốc độ di chuyển của người: " + tocDo + " km/h. Khá nhanh đó!");
    }
}

// Bước 3: Sử dụng Interface trong chương trình chính - Phép thuật đa hình!
public class ChuongTrinhDiChuyen {
    public static void main(String[] args) {
        DiChuyenDuoc phuongTien1 = new XeOto();
        DiChuyenDuoc phuongTien2 = new MayBay();
        DiChuyenDuoc phuongTien3 = new ConNguoi();

        System.out.println("--- Phương tiện 1 ---");
        phuongTien1.diChuyen("phía Bắc");
        phuongTien1.thongBaoTocDo(60);
        phuongTien1.dungLai();

        System.out.println("\n--- Phương tiện 2 ---");
        phuongTien2.diChuyen("phía Đông");
        phuongTien2.thongBaoTocDo(800);
        phuongTien2.dungLai();
        
        System.out.println("\n--- Phương tiện 3 ---");
        phuongTien3.diChuyen("quán trà sữa");
        phuongTien3.thongBaoTocDo(5);
        phuongTien3.dungLai();
    }
}

Output của đoạn code trên:

--- Phương tiện 1 ---
Xe ô tô đang lăn bánh về phía phía Bắc.
Tốc độ hiện tại: 60 km/h
Xe ô tô đã dừng lại.

--- Phương tiện 2 ---
Máy bay đang cất cánh và bay về phía Đông.
Tốc độ hiện tại: 800 km/h
Máy bay đã hạ cánh an toàn.

--- Phương tiện 3 ---
Con người đang đi bộ về quán trà sữa.
Tốc độ di chuyển của người: 5 km/h. Khá nhanh đó!
Con người đã đứng lại.

Thấy chưa? Dù là XeOto, MayBay, hay ConNguoi, tất cả đều phải có phương thức diChuyen()dungLai(). Nhưng cách họ thực hiện thì lại hoàn toàn khác nhau. Đó chính là sức mạnh của đa hình (polymorphism) thông qua Interface!

Illustration

3. Mẹo hay Creyt "bóc phốt" cho anh em

  • Ghi nhớ "Hợp đồng": Cứ nghĩ Interface là một bản hợp đồng. Ai ký hợp đồng đó (implement Interface) thì phải thực hiện đầy đủ các điều khoản (override tất cả các phương thức trừu tượng). Không làm là "vi phạm hợp đồng", compiler nó "kêu" liền!
  • Tính kế thừa "đa năng": Java không cho phép đa kế thừa (một lớp không thể kế thừa từ nhiều lớp cha), nhưng nó cho phép một lớp implement nhiều Interface. Đây là cách Java "lách luật" để đạt được tính đa kế thừa về hành vi. Một lớp có thể vừa là XeOto, vừa DiChuyenDuoc, vừa BaoTriDuoc, vừa CoTheDoXang... "Đa zi năng" là ở đây chứ đâu!
  • Luôn là public abstract: Các phương thức trong Interface mặc định là public abstract (trừ default, static, private methods). Các trường (fields) mặc định là public static final. Bạn không cần viết tường minh, compiler tự hiểu.
  • Interface không có constructor: Interface không thể được khởi tạo trực tiếp (new DiChuyenDuoc() là lỗi). Nó chỉ là một "khuôn mẫu" hành vi mà thôi.

4. Từ Harvard đến thực tế cuộc sống Gen Z

Trong giới lập trình chuyên nghiệp, Interface được coi là một công cụ thiết yếu để xây dựng kiến trúc phần mềm linh hoạt, dễ bảo trì và mở rộng. Nó thúc đẩy nguyên tắc "program to an interface, not an implementation" (lập trình dựa trên giao diện, không phải dựa trên cách triển khai cụ thể).

Nghĩa là, khi bạn viết code, thay vì yêu cầu một đối tượng cụ thể như XeOto, bạn hãy yêu cầu một đối tượng có khả năng DiChuyenDuoc. Điều này giúp code của bạn ít phụ thuộc vào chi tiết triển khai, dễ dàng thay đổi loại đối tượng mà không cần sửa đổi nhiều code.

5. Ứng dụng thực tế: "Đã thấy ở đâu?"

  • Android Development: Các bạn dùng Android Studio chắc chắn đã gặp OnClickListener, OnTouchListener. Đó chính là các Interface! Khi bạn muốn một nút bấm (Button) phản ứng khi được chạm vào, bạn implement OnClickListener và override phương thức onClick(). Android chỉ cần biết đối tượng của bạn có khả năng onClick() là đủ, không cần biết đối tượng đó là cái gì cụ thể.
  • Java Collections Framework: Các Interface như List, Set, Map, Iterable là xương sống. ArrayListLinkedList đều implement List, nghĩa là chúng đều có các hành vi cơ bản của một danh sách (thêm, xóa, truy cập phần tử) nhưng cách chúng thực hiện lại khác nhau.
  • JDBC (Java Database Connectivity): Các Interface như Connection, Statement, ResultSet cho phép Java tương tác với nhiều loại cơ sở dữ liệu khác nhau (MySQL, PostgreSQL, Oracle) mà không cần thay đổi code truy vấn, miễn là có driver phù hợp.
  • Google Maps API, Facebook Login API: Khi các nhà phát triển muốn tích hợp bản đồ của Google hoặc tính năng đăng nhập của Facebook vào ứng dụng của họ, họ sẽ tương tác thông qua một bộ các phương thức mà Google/Facebook cung cấp. Đó là một dạng Interface, định nghĩa cách bạn có thể "nói chuyện" với dịch vụ của họ mà không cần biết nội bộ họ làm gì.

6. Khi nào nên "triển" Interface?

Creyt khuyên bạn nên "triển" Interface trong các trường hợp sau:

  • Định nghĩa hợp đồng hành vi: Khi bạn muốn một nhóm các lớp khác nhau phải có chung một tập hợp các hành vi, nhưng cách thực hiện hành vi đó lại tùy thuộc vào từng lớp.
  • Hỗ trợ đa kế thừa hành vi: Khi một lớp cần có nhiều "khả năng" hoặc "vai trò" khác nhau mà Java không cho phép kế thừa nhiều lớp cha.
  • Tạo sự linh hoạt và khả năng mở rộng (Extensibility): Cho phép thêm các triển khai mới của một Interface mà không ảnh hưởng đến code hiện có. Ví dụ, bạn có thể dễ dàng thêm XeDap hay TauHoa vào hệ thống DiChuyenDuoc mà không cần sửa đổi ChuongTrinhDiChuyen.
  • Thiết kế API: Khi bạn xây dựng thư viện hoặc framework mà muốn các nhà phát triển khác có thể tùy chỉnh hoặc mở rộng các chức năng của bạn.
  • Đa hình và Dependency Injection: Dùng Interface là cách "sạch" nhất để đạt được đa hình và là nền tảng cho các kỹ thuật như Dependency Injection, giúp giảm sự phụ thuộc giữa các module trong ứng dụng.

Thử nghiệm đã từng: Creyt đã từng thấy nhiều bạn sinh viên mới học cố gắng nhét hết logic vào Interface bằng cách dùng default method quá nhiều. Nhớ nhé, default method chỉ nên dùng cho các hành vi chungkhông bắt buộc mà hầu hết các lớp implement đều có thể dùng chung. Nếu logic quá phức tạp hoặc có sự khác biệt lớn, hãy để các lớp implement tự định nghĩa.

Interface không chỉ là một "keyword" trong Java, nó là một "tư duy thiết kế" giúp bạn viết code "sạch", "linh hoạt" và "chuẩn pro". Cứ luyện tập nhiều, "skill" của bạn sẽ "auto-level-up" thôi!

Chúc các bạn code vui vẻ và luôn "on-top"!

Thuộc Series: Java – OOP

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!