Menu

Interface trong Java: định nghĩa hợp đồng và implements

Interface trong Java là gì, cách khai báo và triển khai interface, phương thức default và static, và interface khác lớp trừu tượng ở điểm nào.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Interface là một bản hợp đồng

Interface khai báo một lớp làm được gì mà không nói làm thế nào. Đó là danh sách các chữ ký phương thức (method signature) mà mọi lớp triển khai cam kết thực hiện. Mục đích là tách rời (decoupling): code có thể làm việc với kiểu interface mà không cần quan tâm lớp cụ thể nào đứng phía sau.

Circle implements Shape nghĩa là Circle phải định nghĩa area và perimeter. Khi đã làm vậy, một Circle là một Shape và có thể lưu trong biến kiểu Shape.

Nhiều lớp, một kiểu

Sức mạnh của interface lộ rõ khi nhiều lớp không liên quan cùng triển khai một interface. Code viết cho Shape xử lý được tất cả:

Vòng lặp không bao giờ hỏi "đây là Circle hay Rectangle?". Nó chỉ gọi area() và tin vào hợp đồng. Sau này thêm một lớp Triangle cũng không cần sửa gì ở đây.

Triển khai nhiều interface

Một lớp chỉ kế thừa (extends) được một lớp, nhưng có thể triển khai bao nhiêu interface cũng được. Đây là cách Java hỗ trợ "đa kế thừa" hành vi một cách an toàn:

Liệt kê các interface sau implements, cách nhau bằng dấu phẩy. Lớp phải đáp ứng tất cả các interface đó.

Phương thức default và static

Từ Java 8, interface có thể chứa thân phương thức. Phương thức default cho các lớp triển khai một phần cài đặt có sẵn, được thừa hưởng miễn phí (và có thể ghi đè):

Phương thức default giúp interface phát triển thêm: bạn thêm phương thức mới mà không làm hỏng mọi lớp đã triển khai. Ngược lại, phương thức interface static hoạt động như các thành viên static khác: đó là tiện ích bạn gọi trực tiếp trên interface, ví dụ Comparator.naturalOrder().

Hằng số

Các trường khai báo trong interface ngầm định là public static final: chúng là hằng số, không phải trạng thái của instance:

interface Physics {
    double GRAVITY = 9.81;   // automatically public static final
}

Theo truyền thống, interface không giữ trạng thái riêng cho từng đối tượng; việc không có trường instance là một phần khiến interface khác với lớp.

Functional interface

Interface có đúng một phương thức trừu tượng được gọi là functional interface, và bạn có thể triển khai nó bằng một biểu thức lambda thay vì viết cả một lớp:

Đây là nền tảng của lambda trong Java và các kiểu trong java.util.function (Function, Predicate, Supplier và nhiều kiểu khác). Annotation @FunctionalInterface thể hiện rõ ý định và để trình biên dịch kiểm tra quy tắc chỉ có một phương thức.

Interface và abstract class

Cả hai đều cho phép bạn lập trình dựa trên một lớp trừu tượng hóa, vậy khi nào chọn cái nào?

  • Interface: một khả năng mà các lớp không liên quan có thể cùng có. Bird và Airplane đều có thể là Flyable. Một lớp có thể triển khai nhiều interface. Không có trạng thái instance.
  • Abstract class (lớp trừu tượng): trạng thái và code dùng chung giữa các lớp có quan hệ gần gũi. Cat và Dog đều kế thừa Animal, thừa hưởng các trường chung và các phương thức đã viết sẵn một phần. Một lớp chỉ kế thừa được một lớp.

Một cách làm phổ biến là kết hợp cả hai: interface định nghĩa hợp đồng, lớp trừu tượng cài đặt phần code lặp lại (boilerplate), để các lớp con cụ thể chỉ cần viết phần riêng của mình.

Tiếp theo: lớp trừu tượng

Interface định nghĩa hành vi mà không có trạng thái. Lớp trừu tượng nằm giữa interface và lớp đầy đủ: nó có thể khai báo các phương thức chưa cài đặt và đồng thời có trường và hàm khởi tạo. Đó là nội dung của trang tiếp theo.

Câu hỏi thường gặp

Interface trong Java là gì?

Interface là một bản hợp đồng: tập hợp các chữ ký phương thức (và hằng số) mà một lớp cam kết cung cấp. Interface nói lớp làm được gì, không nói làm thế nào. Lớp dùng từ khóa implements để nhận một interface và phải viết thân cho mọi phương thức trừu tượng mà interface đó khai báo. Nhờ interface, các lớp không liên quan đến nhau vẫn dùng thay thế cho nhau được qua một kiểu chung.

Interface và abstract class trong Java khác nhau thế nào?

Một lớp có thể triển khai nhiều interface nhưng chỉ kế thừa được một lớp (trừu tượng). Theo truyền thống, interface không giữ trạng thái của instance và chỉ khai báo hành vi, còn lớp trừu tượng có thể có thuộc tính, hàm khởi tạo và phần logic đã viết sẵn một phần. Dùng interface để định nghĩa một khả năng mà nhiều lớp không liên quan cùng có; dùng lớp trừu tượng để chia sẻ trạng thái và code chung giữa các lớp con có quan hệ gần gũi.

Interface trong Java có thể có thân phương thức không?

Có, từ Java 8. Phương thức interface đánh dấu default có thân mà các lớp triển khai được thừa hưởng (và có thể ghi đè), còn phương thức interface static cung cấp tiện ích gọi trực tiếp trên chính interface. Các phương thức interface thông thường vẫn là trừu tượng, chỉ có chữ ký, và lớp triển khai phải tự định nghĩa chúng.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu