Một giao diện có thể được sử dụng để xác định một hành vi hợp đồng và nó cũng có thể hoạt động như một hợp đồng giữa hai hệ thống để tương tác trong khi một lớp trừu tượng chủ yếu được sử dụng để xác định hành vi mặc định cho các lớp con, điều đó có nghĩa là tất cả các lớp con phải thực hiện cùng một chức năng.
Khi nào sử dụng một lớp trừu tượng
- Một lớp trừu tượng là một lựa chọn tốt nếu chúng ta đang sử dụng khái niệm kế thừa vì nó cung cấp cách triển khai lớp cơ sở chung cho các lớp dẫn xuất.
- Một lớp trừu tượng cũng tốt nếu chúng ta muốn khai báo các thành viên không phải là công khai. Trong một giao diện, tất cả các phương thức phải ở chế độ công khai.
- Nếu chúng ta muốn thêm các phương thức mới trong tương lai, thì một lớp trừu tượng là lựa chọn tốt hơn. Bởi vì nếu chúng tôi thêm các phương thức mới vào một giao diện, thì tất cả các lớp đã triển khai giao diện đó sẽ phải được thay đổi để triển khai các phương thức mới.
- Nếu chúng tôi muốn tạo nhiều phiên bản thành phần của mình, hãy tạo một lớp trừu tượng. Các lớp trừu tượng cung cấp một cách đơn giản và dễ dàng để phiên bản các thành phần của chúng ta. Bằng cách cập nhật lớp cơ sở, tất cả các lớp kế thừa được tự động cập nhật với sự thay đổi. Mặt khác, không thể thay đổi giao diện sau khi được tạo. Nếu cần có phiên bản giao diện mới, chúng tôi phải tạo một giao diện hoàn toàn mới.
- Các lớp trừu tượng có lợi thế là cho phép khả năng tương thích chuyển tiếp tốt hơn. Khi khách hàng sử dụng giao diện, chúng tôi không thể thay đổi giao diện đó; nếu họ sử dụng một lớp trừu tượng, chúng tôi vẫn có thể thêm hành vi mà không phá vỡ mã hiện có.
- Nếu chúng tôi muốn cung cấp chức năng phổ biến, được triển khai trong số tất cả các triển khai của thành phần của chúng tôi, hãy sử dụng một lớp trừu tượng. Các lớp trừu tượng cho phép chúng tôi triển khai một phần lớp của mình, trong khi các giao diện không chứa phần triển khai nào cho bất kỳ thành viên nào.
Ví dụ
abstract class Car { public void accelerate() { System.out.println("Do something to accelerate"); } public void applyBrakes() { System.out.println("Do something to apply brakes"); } public abstract void changeGears(); }
Bây giờ, bất kỳ Xe ô tô nào muốn được khởi tạo đều phải triển khai phương thức changeGears ().
class Alto extends Car { public void changeGears() { System.out.println("Implement changeGears() method for Alto Car"); } } class Santro extends Car { public void changeGears() { System.out.println("Implement changeGears() method for Santro Car"); } }
Khi nào sử dụng giao diện
- Nếu chức năng chúng tôi đang tạo hữu ích trên nhiều đối tượng khác nhau, hãy sử dụng một giao diện. Các lớp trừu tượng nên được sử dụng chủ yếu cho các đối tượng có liên quan chặt chẽ với nhau, trong khi các giao diện là phù hợp nhất để cung cấp chức năng chung cho các lớp không liên quan.
- Giao diện là một lựa chọn tốt khi chúng tôi nghĩ rằng API sẽ không thay đổi trong một thời gian.
- Các giao diện cũng rất tốt khi chúng tôi muốn có thứ gì đó tương tự với nhiều giao diện kế thừa vì chúng tôi có thể triển khai nhiều giao diện.
- Nếu chúng tôi đang thiết kế các bit chức năng nhỏ, ngắn gọn, hãy sử dụng các giao diện. Nếu chúng tôi đang thiết kế các đơn vị chức năng lớn, hãy sử dụng một lớp trừu tượng.
Ví dụ
public interface Actor { void perform(); } public interface Producer { void invest(); }
Ngày nay hầu hết các diễn viên đều đủ giàu để sản xuất phim của riêng họ. Nếu chúng ta đang sử dụng các giao diện thay vì các lớp trừu tượng, chúng ta có thể triển khai cả Actor và Producer. Ngoài ra, chúng ta có thể xác định giao diện ActorProduction mới mở rộng cả hai.
public interface ActorProducer extends Actor, Producer{ // some statements }