Trình bày bởi: Sơn Dương
Giới thiệu
Trong diễn đàn VOZ, có một câu hỏi được đặt lên: "Interface trong Java là gì? Nó khác với Abstract Class ở điểm nào? Tại sao phải sử dụng Interface khi nó không giúp rút gọn mã nguồn và thậm chí còn làm dài nó?" Mặc dù đã có nhiều câu trả lời cho câu hỏi này, nhưng hầu hết đều hiểu sai hoặc chưa thực sự thấu hiểu bản chất của Interface trong Java.
Bài viết này sẽ giúp các bạn có cái nhìn sâu sắc và hiểu rõ bản chất của Interface. Từ đó, bạn có thể áp dụng Interface một cách chuẩn mực cho dự án của mình.
Java Interface là gì? Đó là "bộ mặt" của Java à?
Để hiểu một cách chính xác, chúng ta cần đọc định nghĩa của Oracle:
Oracle cũng không thể định nghĩa Interface theo cách khoa học như: "Interface là xyz, bla bla". Nhưng chúng ta có thể hiểu một cách đơn giản và chính xác như sau: Trong thế giới thực, chúng ta có đồ vật (đồ vật, con vật...) và hành vi của chúng. Interface được sinh ra để định nghĩa các hành vi của một nhóm đối tượng.
Hãy xem ví dụ sau: Một con mèo (đây là một đồ vật) thì có các hành vi như: chạy, bắt chuột, ngủ...
Chúng ta sẽ định nghĩa một Interface với tên là "Cat":
interface Cat {
void run();
void catchMouse();
void sleep();
}
Khi chúng ta định nghĩa một con mèo, chúng ta sẽ cần các hành vi của con mèo, dù đó là mèo tam thể hay mèo vàng...
Về mặt học thuật, Interface chính là khái niệm để thực hiện triết lý đa hình trong lập trình hướng đối tượng. Cụ thể hơn, tôi sẽ giải thích ở phần sau của bài viết.
Interface trong Java cũng là một Abstract Class bao gồm các phương thức được định nghĩa (nhưng nội dung của phương thức không được viết cụ thể, người ta gọi là phương thức trừu tượng). Một Class sau này sẽ implements một Interface, và khi đó Class mới viết cụ thể nội dung của các phương thức được định nghĩa trong Interface.
Ngoài các phương thức trừu tượng, bạn cũng có thể thêm hằng số, phương thức tĩnh, interface lồng nhau (interface trong một interface) và phương thức mặc định vào trong Interface.
Điểm giống và khác nhau giữa Interface và Abstract Class
Interface và Abstract Class cơ bản giống nhau. Cả hai đều có các phương thức trừu tượng và các phương thức được thiết kế để được implement trong các lớp khác. Quá trình implement này tương tự với việc kế thừa và ghi đè phương thức trong Abstract Class.
Tuy nhiên, tôi thấy có hai điểm khác biệt chính:
- Về cách viết code:
- Các phương thức trong Interface phải là phương thức trống, tức là không có nội dung, chỉ có tên phương thức, tham số và kiểu dữ liệu trả về. Trong khi đó, trong Abstract Class, bạn hoàn toàn có thể thêm phương thức trừu tượng hoặc phương thức bình thường (có nội dung và logic trong thân phương thức).
- Về mục đích sử dụng:
- Interface là một tính năng mà bạn có thể thêm vào bất kỳ lớp nào. Tính năng ở đây không đồng nghĩa với phương thức.
- Abstract Class là một lớp cha cho tất cả các lớp có cùng bản chất. Bản chất ở đây có nghĩa là loại, kiểu và nhiệm vụ của lớp.
Tại sao chúng ta cần Interface?
Lý do chính là Java không hỗ trợ đa kế thừa. Do đó, bạn không thể kế thừa cùng lúc từ nhiều lớp. Các lớp con không thể kế thừa các thuộc tính từ nhiều lớp cha, vì điều này dẫn đến vấn đề "Kim Cương" (bạn có thể tìm hiểu thêm về vấn đề này trên Google).
Để giải quyết vấn đề này, người ta đã tạo ra Interface. Hãy xem ví dụ dưới đây để hiểu rõ hơn.
Giả sử bạn muốn thiết kế một Sở thú, trong đó có rất nhiều loại động vật. Cơ bản, tất cả các động vật đều có những đặc điểm chung như: có tên, có tiếng kêu, có chân (2 chân, 4 chân hoặc không có chân...). Từ những đặc điểm chung đó, bạn tạo ra một Abstract Class là "Animal".
Tuy nhiên, một số loài biết bay, một số loài biết bơi và một số loài cả biết bay và bơi. Do đó, bạn không thể đặt các đặc điểm bay hoặc bơi trong lớp Animal.
Đó là lý do tại sao chúng ta cần tạo hai Interface riêng biệt là "Can_Fly" và "Can_Swim", rồi xem lớp nào có thể implements từng Interface phù hợp.
Đặc điểm chính của Java Interface
Bạn đã hiểu một phần về Interface trong Java, phải không? Bạn đã hiểu khi nào cần sử dụng Interface và khác biệt của nó so với lớp thông thường.
Dưới đây là các đặc điểm chính mà bạn cần nhớ về Interface:
- Các phương thức được khai báo trong Interface phải là phương thức trống.
- Không thể tạo đối tượng từ Interface.
- Một lớp có thể implements một hoặc nhiều Interface.
Dưới đây là một ví dụ code để minh họa:
interface Circle {
double PI = 3.14;
double calculateArea(double radius);
}
class CircleImplementation implements Circle {
@Override
public double calculateArea(double radius) {
return PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
Circle circle = new CircleImplementation();
double area = circle.calculateArea(5);
System.out.println("Diện tích hình tròn là: " + area);
}
}
Kết quả khi chạy đoạn code trên là: "Diện tích hình tròn là: 78.5".
Tổng kết
Như vậy, bạn đã hoàn thành việc đọc bài viết về Interface trong Java. Bạn đã "hiểu hơn một chút" rồi chứ? Nếu chưa, thì... buồn thật đấy.
Hãy nhớ rằng, Interface chỉ là một công cụ, nó không phải là triết lý lập trình. Vì vậy, khi ai đó nói về lập trình hướng đối tượng và tính đa hình, đừng nhầm lẫn rằng "Tính đa hình là Interface". Đây chỉ là một công cụ để thực hiện tính đa hình.
Bài viết gốc được đăng tải tại vntalking.com.