Trong Java, cả interfaceabstract class đều được sử dụng để định nghĩa các hành vi trừu tượng, nhưng chúng có những điểm khác nhau về cách sử dụng và vai trò. Hiểu rõ sự khác biệt giữa chúng là rất quan trọng để sử dụng hiệu quả trong lập trình hướng đối tượng.

1. Khái niệm về Interface và Abstract Class

Interface

  • Interface trong Java là một bản thiết kế của một lớp. Nó chỉ chứa các phương thức trừu tượng (abstract methods) mà không có phần triển khai (implementation).
  • Bắt đầu từ Java 8, interface có thể có phương thức mặc định (default methods) và phương thức tĩnh (static methods) có phần triển khai.
  • Một lớp có thể implements (kế thừa) nhiều interfaces, cho phép kế thừa đa hình.

Abstract class

  • Abstract class là một lớp không thể khởi tạo trực tiếp mà phải được kế thừa. Nó có thể chứa cả phương thức trừu tượngphương thức cụ thể (implemented methods).
  • Một lớp có thể extends (kế thừa) chỉ một abstract class duy nhất.
  • Abstract class có thể có constructor, biến instance (instance variables), và phương thức static.

2. Sự khác biệt chi tiết giữa Interface và Abstract Class

Đặc điểmInterfaceAbstract Class
Kế thừaLớp có thể implements nhiều interfaces.Lớp chỉ có thể extends một abstract class.
Phương thứcChỉ có phương thức trừu tượng (cho đến Java 7). Từ Java 8 trở đi, có thể có phương thức mặc địnhphương thức tĩnh.Có thể có cả phương thức trừu tượng lẫn phương thức cụ thể (đã triển khai).
ConstructorKhông thể có constructor.Có thể có constructor và được gọi khi lớp con được khởi tạo.
BiếnChỉ có thể có các biến static và final (hằng số).Có thể có cả biến instance, biến static, và biến final.
Đa kế thừaHỗ trợ đa kế thừa (một lớp có thể kế thừa nhiều interfaces).Không hỗ trợ đa kế thừa (chỉ có thể kế thừa một abstract class).
Mục đích sử dụngSử dụng khi muốn định nghĩa hành vi (behaviors) mà các lớp con phải tuân theo.Sử dụng khi muốn cung cấp một lớp cơ sở với một phần triển khai mặc định và phần còn lại sẽ do các lớp con thực hiện.
Từ khóa mặc địnhCác phương thức trong interface mặc định là publicabstract (nếu không có phần triển khai).Các phương thức có thể có bất kỳ modifier nào (public, protected, hoặc private).
Tính linh hoạtĐược sử dụng để định nghĩa API chung mà nhiều lớp có thể thực hiện với các hành vi khác nhau.Được sử dụng khi có một số hành vi chung nhưng muốn cung cấp triển khai mặc định cho một số phần.
Tính năng bổ sungTừ Java 8, có thể thêm các phương thức mặc định (default methods) và phương thức tĩnh.Có thể chứa constructor, block khởi tạo, phương thức staticnon-static methods.

3. Khi nào sử dụng Interface, khi nào sử dụng Abstract Class?

  • Sử dụng Interface khi:
    • Bạn cần định nghĩa hành vi chung mà các lớp khác nhau có thể chia sẻ, nhưng không quan tâm đến việc triển khai của chúng.
    • Bạn muốn hỗ trợ đa kế thừa (vì một lớp có thể kế thừa nhiều interfaces).
    • Bạn muốn tách biệt phần API ra khỏi phần triển khai để dễ dàng mở rộng sau này.
  • Sử dụng Abstract Class khi:
    • Bạn có một vài hành vi mặc định và muốn các lớp con chia sẻ, nhưng cũng muốn các lớp con có thể cung cấp phần triển khai cụ thể của riêng chúng.
    • Bạn muốn cung cấp các thuộc tính (fields)phương thức có thể được chia sẻ giữa các lớp con.
    • Bạn muốn kiểm soát chặt chẽ về việc kế thừa, vì các lớp chỉ có thể kế thừa một abstract class duy nhất.

4. Ví dụ về Interface và Abstract Class

Interface

interface Animal {
    void sound(); // Phương thức trừu tượng
    default void sleep() {
        System.out.println("The animal is sleeping.");
    }
}

class Dog implements Animal {
    public void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // Gọi phương thức của lớp Dog
        dog.sleep();  // Gọi phương thức mặc định từ interface Animal
    }
}

Abstract Class

abstract class Animal {
    abstract void sound(); // Phương thức trừu tượng
    void sleep() {
        System.out.println("The animal is sleeping.");
    }
}

class Dog extends Animal {
    public void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // Gọi phương thức của lớp Dog
        dog.sleep();  // Gọi phương thức đã được triển khai từ abstract class Animal
    }
}

5. Kết luận

Interface và Abstract Class đều là các công cụ mạnh mẽ trong Java để xây dựng các hệ thống lập trình hướng đối tượng. Sự khác biệt chính giữa chúng nằm ở cách chúng quản lý đa kế thừa và cách chúng xử lý việc triển khai các phương thức. Interface linh hoạt hơn về mặt đa kế thừa, trong khi abstract class cung cấp khả năng chia sẻ logic giữa các lớp con.

Tùy thuộc vào yêu cầu cụ thể của hệ thống, bạn có thể chọn giữa interface hoặc abstract class để đảm bảo thiết kế phần mềm linh hoạt, dễ bảo trì và mở rộng.