Implements trong Java: Hợp đồng code cho GenZ
Java – OOP

Implements trong Java: Hợp đồng code cho GenZ

Author

Admin System

@root

Ngày xuất bản

20 Mar, 2026

Lượt xem

2 Lượt

implements keyword

Chào các chiến thần GenZ, hôm nay chúng ta sẽ cùng anh Creyt "bóc tách" một khái niệm siêu "cool" trong Java, đó chính là từ khóa implements. Nghe có vẻ khô khan nhưng tin anh đi, nó thú vị hơn cả việc lướt TikTok đấy!

implements là gì và để làm gì? (aka "Hợp đồng Code" của GenZ)

Trong thế giới lập trình, implements giống như một bản hợp đồng ràng buộc giữa một Class và một Interface. Tưởng tượng thế này: bạn muốn xây dựng một ứng dụng quản lý "pet cưng" với các loại pet khác nhau như chó, mèo, chim... Mỗi con pet dù khác loài nhưng đều có những hành vi chung như "ăn", "ngủ", "chơi".

Thay vì viết đi viết lại từng hành vi cho từng loài, chúng ta tạo ra một Interface – tạm gọi là HanhViThuCung. Interface này chỉ định nghĩa những hành vi cần có (như an(), ngu(), choi()) mà không quan tâm đến cách chúng được thực hiện. Nó giống như một danh sách "to-do list" mà thôi.

Khi một Class (ví dụ Class Cho hay Class Meo) sử dụng từ khóa implements HanhViThuCung, nó đang ký vào bản hợp đồng đó. Và khi đã ký thì bắt buộc phải thực hiện tất cả các điều khoản trong hợp đồng – tức là phải cung cấp phần thân (implementation) cho tất cả các phương thức đã được khai báo trong Interface (an(), ngu(), choi()). Nếu không, Java compiler sẽ "giận dỗi" và không cho code của bạn chạy đâu!

Vậy implements sinh ra để làm gì?

  1. Đảm bảo tính nhất quán (Consistency): Giúp các đối tượng khác nhau (Chó, Mèo) dù có cách thực hiện khác nhau nhưng vẫn "nói chuyện" được với nhau qua một giao diện chung. Như kiểu mọi app mạng xã hội đều có chức năng "đăng bài", nhưng cách đăng bài của TikTok khác với Facebook vậy.
  2. Tính mở rộng (Extensibility): Dễ dàng thêm các loại pet mới (Chim, Cá...) vào ứng dụng mà không làm ảnh hưởng đến cấu trúc code hiện có. Chỉ cần tạo Class Chim implements HanhViThuCung là xong.
  3. Đa hình (Polymorphism): Cho phép bạn coi nhiều đối tượng thuộc các class khác nhau như cùng một kiểu nếu chúng cùng implements một interface. "Mọi con vật có thể ăn", nên bạn có thể tạo một danh sách List<HanhViThuCung> chứa cả Chó, Mèo, Chim.

Code Ví Dụ Minh Hoạ: Điện Thoại Thông Minh

Để dễ hình dung hơn, chúng ta hãy xem ví dụ về các hãng điện thoại thông minh. Mỗi hãng có cách thực hiện riêng nhưng đều có những chức năng cốt lõi như gọi điện, nhắn tin, chụp ảnh.

Gợi Ý Đọc Tiếp
Constructor: Phù Thủy Khai Sinh Object trong Java OOP

7 Lượt xem

// Bước 1: Tạo "hợp đồng" - Interface định nghĩa các hành vi cốt lõi của điện thoại
interface HanhViDienThoai { 
    void goiDien(String soDienThoai);
    void nhanTin(String soDienThoai, String tinNhan);
    void chupAnh();
}

// Bước 2: "Nhà sản xuất" Apple ký hợp đồng và thực hiện lời hứa của mình
class IPhone implements HanhViDienThoai {
    @Override // Annotation này giúp kiểm tra xem phương thức có override đúng không
    public void goiDien(String soDienThoai) {
        System.out.println("IPhone đang gọi đến số: " + soDienThoai + " bằng FaceTime Audio.");
    }

    @Override
    public void nhanTin(String soDienThoai, String tinNhan) {
        System.out.println("IPhone đang gửi iMessage đến số: " + soDienThoai + " với nội dung: '" + tinNhan + "'");
    }

    @Override
    public void chupAnh() {
        System.out.println("IPhone chụp ảnh với chế độ Portrait Mode siêu nét!");
    }

    // IPhone có thể có các hành vi riêng khác không có trong hợp đồng
    public void dungSiri() {
        System.out.println("Hey Siri, mở nhạc!");
    }
}

// Bước 3: "Nhà sản xuất" Samsung cũng ký hợp đồng và thực hiện lời hứa theo cách riêng
class Samsung implements HanhViDienThoai {
    @Override
    public void goiDien(String soDienThoai) {
        System.out.println("Samsung đang gọi đến số: " + soDienThoai + " qua mạng 5G.");
    }

    @Override
    public void nhanTin(String soDienThoai, String tinNhan) {
        System.out.println("Samsung đang gửi SMS đến số: " + soDienThoai + " với nội dung: '" + tinNhan + "'");
    }

    @Override
    public void chupAnh() {
        System.out.println("Samsung chụp ảnh với chế độ Night Mode cực đỉnh!");
    }

    // Samsung cũng có thể có các hành vi riêng khác
    public void dungBixby() {
        System.out.println("Hi Bixby, bật đèn!");
    }
}

// Bước 4: Chạy thử và thấy sức mạnh của "hợp đồng" chung
public class DienThoaiApp {
    public static void main(String[] args) {
        // Khai báo kiểu Interface, nhưng khởi tạo bằng class cụ thể (đa hình)
        HanhViDienThoai myIphone = new IPhone();
        HanhViDienThoai mySamsung = new Samsung();

        System.out.println("--- Dùng IPhone --- ");
        myIphone.goiDien("0912345678");
        myIphone.nhanTin("0987654321", "Alo, bạn khỏe không?");
        myIphone.chupAnh();
        // myIphone.dungSiri(); // Lỗi! Không thể gọi phương thức riêng qua kiểu interface HanhViDienThoai

        System.out.println("\n--- Dùng Samsung --- ");
        mySamsung.goiDien("0334567890");
        mySamsung.nhanTin("0909090909", "Hẹn gặp nhé!");
        mySamsung.chupAnh();

        // Một hàm có thể nhận bất kỳ đối tượng nào implement HanhViDienThoai
        System.out.println("\n--- Kiểm tra chung các điện thoại --- ");
        kiemTraDienThoai(myIphone);
        kiemTraDienThoai(mySamsung);
    }

    // Hàm này không cần biết đó là IPhone hay Samsung, chỉ cần biết nó là "một cái điện thoại"
    public static void kiemTraDienThoai(HanhViDienThoai dt) {
        System.out.println("--- Đang kiểm tra một điện thoại bất kỳ ---");
        dt.goiDien("113");
        dt.chupAnh();
    }
}
Illustration

Mẹo hay (Best Practices) để "chơi" với implements

  1. Nhớ "ký hợp đồng" đầy đủ: Khi bạn implements một Interface, hãy chắc chắn rằng bạn đã cung cấp phần thân cho tất cả các phương thức được khai báo trong đó. Đây là quy tắc vàng, nếu không compiler sẽ "gank" bạn ngay lập tức.
  2. Interface là "cánh cổng": Thay vì khai báo biến hay tham số hàm bằng kiểu Class cụ thể (ví dụ IPhone myPhone = new IPhone();), hãy dùng kiểu Interface (ví dụ HanhViDienThoai myPhone = new IPhone();). Điều này giúp code của bạn linh hoạt hơn, dễ dàng thay đổi loại điện thoại mà không cần sửa nhiều chỗ.
  3. Tên Interface có "hint": Thường thì các Interface trong Java hay có tên kết thúc bằng -able (ví dụ Runnable, Comparable, Serializable) hoặc đôi khi bắt đầu bằng chữ I (như IList trong C#, dù Java ít dùng hơn). Điều này giúp bạn dễ nhận diện đó là một Interface.
  4. "Hợp đồng" nhỏ, chuyên biệt: Đừng cố gắng tạo ra một Interface quá lớn, ôm đồm quá nhiều chức năng. Mỗi Interface nên tập trung vào một nhóm hành vi cụ thể, rõ ràng. Điều này giúp code dễ hiểu, dễ quản lý và tái sử dụng hơn.
  5. default methods (Java 8+): Đây là một "điều khoản phụ" cực hay trong hợp đồng. Nó cho phép bạn thêm một phương thức có cài đặt mặc định vào Interface mà không làm hỏng các Class đã implements nó trước đó. Như kiểu thêm một tính năng mới vào điện thoại mà các hãng không cần phải cập nhật lại từ đầu vậy.

Ví dụ thực tế các ứng dụng/website đã ứng dụng

implementsInterface là xương sống của rất nhiều framework và thư viện Java:

  • Android Development: Khi bạn tạo các nút bấm, ô nhập liệu trên ứng dụng Android, bạn thường phải implements các Listener như OnClickListener hay TextWatcher. Đây là cách bạn nói cho hệ thống biết "khi có sự kiện này xảy ra, hãy gọi phương thức của tôi".
  • Java Collections Framework: Các cấu trúc dữ liệu quen thuộc như List, Set, Map đều là Interface. Các Class cụ thể như ArrayList, HashSet, HashMap sẽ implements chúng. Điều này cho phép bạn viết code chung cho List mà không cần quan tâm nó là ArrayList hay LinkedList phía dưới.
  • Spring Framework: Trong Spring, bạn sẽ thấy rất nhiều Interface được dùng để định nghĩa các dịch vụ (Services), kho lưu trữ dữ liệu (Repositories). Điều này giúp bạn dễ dàng thay đổi cách thức lưu trữ dữ liệu (ví dụ từ MySQL sang MongoDB) mà không cần chỉnh sửa quá nhiều code ở tầng logic ứng dụng.
  • JDBC (Java Database Connectivity): Các đối tượng như Connection, Statement, ResultSet đều là Interface. Các nhà cung cấp cơ sở dữ liệu (Oracle, MySQL, PostgreSQL) sẽ cung cấp các driver chứa các Class cụ thể implements những Interface này, giúp bạn kết nối và thao tác với nhiều loại database khác nhau chỉ với một bộ API chung.

Thử nghiệm đã từng và hướng dẫn nên dùng cho case nào

Với kinh nghiệm "chinh chiến" của anh Creyt, anh đã từng thấy nhiều bạn trẻ (và cả anh ngày xưa nữa) loay hoay giữa extendsimplements. Nhớ kỹ điều này:

  • extends (kế thừa Class): Dùng khi có mối quan hệ "là một loại của" (is-a relationship) và bạn muốn tái sử dụng code đã được hiện thực hóa. Ví dụ: Chó extends ĐộngVật (Chó là một loại Động Vật).
  • implements (thực thi Interface): Dùng khi có mối quan hệ "có khả năng làm" (has-a capability) hoặc "có hành vi" (has-a behavior) và bạn muốn định nghĩa một hợp đồng về hành vi mà không quan tâm đến cách nó được thực hiện. Một Class có thể implements nhiều Interface (ký nhiều hợp đồng), nhưng chỉ extends một Class duy nhất.

Anh từng thử nghiệm việc cố gắng nhồi nhét mọi thứ vào một abstract class (class trừu tượng) để tái sử dụng code, nhưng đến lúc cần một class con có hành vi của hai "class cha" khác nhau là "tắc tị" ngay (vì Java không hỗ trợ đa kế thừa class). Đó là lúc Interfaceimplements trở thành "cứu tinh", cho phép một class có thể có nhiều "năng lực" khác nhau từ nhiều Interface.

Nên dùng implements cho các trường hợp sau:

  • Định nghĩa API công cộng: Khi bạn thiết kế một thư viện hoặc module mà các phần khác của hệ thống (hoặc người dùng thư viện của bạn) cần tuân thủ một bộ quy tắc nhất định về cách tương tác.
  • Cơ chế Callback/Event Handling: Trong lập trình sự kiện, một đối tượng cần "thông báo" cho đối tượng khác khi có điều gì đó xảy ra. Đối tượng nhận thông báo sẽ implements một Interface callback để định nghĩa cách nó sẽ phản ứng.
  • Strategy Pattern: Đây là một Design Pattern (mẫu thiết kế) nổi tiếng. Bạn định nghĩa một "họ" các thuật toán, đóng gói mỗi thuật toán thành một Class riêng biệt, và làm cho chúng có thể hoán đổi cho nhau. Mỗi thuật toán sẽ implements một Interface chung.
  • Dependency Inversion Principle (DIP) trong SOLID: Một trong 5 nguyên tắc SOLID, khuyến khích bạn phụ thuộc vào các abstraction (Interface) thay vì các concrete implementation (Class cụ thể). Điều này giúp code dễ kiểm thử (testable), dễ bảo trì và mở rộng hơn rất nhiều.

Đó là tất tần tật về implements keyword, một trong những "siêu năng lực" của OOP trong Java. Hãy thực hành thật nhiều để biến nó thành kỹ năng của riêng bạn nhé, các GenZ! Code là phải "chất", phải "ngầu"!

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!