Chuyển tới nội dung chính

Phân biệt Interface và Abstract class

Hệ thống: MightyLMS - Quản lý giáo dục
Khoá học: Phân biệt Interface và Abstract class
Book: Phân biệt Interface và Abstract class
Được in bởi: Người dùng khách
Ngày: Thứ Sáu, 15 tháng 11 2024, 10:14 AM

Mô tả

Điểm khác biệt cốt lõi cửa 2 thằng này đến từ tư tưởng sử dụng, ko phải đến từ việc thằng này có abc, thằng kia có xyz.

  • Interface giống như 1 bản hợp đồng (contract), tất cả các class implementation của nó phải tuân theo bản hợp đồng đấy. Vì sao lại là contract thì đọc tiếp bên dưới.
  • Abstract class là dùng để thừa kế, mối quan hệ cha-con. Tất cả các class con sẽ được thừa kế những gì của class cha

Nếu nhìn vào điểm khác nhau bạn có thể sẽ nghĩ là “2 thứ nó khác nhau rõ ràng như thế này, sao người ta lại đặt ra câu hỏi là phân biệt 2 thứ này nhỉ?”. Tuy nhiên trên thực tế, nhất là trong Java, về mặt functional thì Interface và Abstract class ko khác nhau nhiều. Sau khi bản update ở Java 8, thì Interface và Abstract class lại càng giống nhau hơn.

Nếu bạn so sánh 2 thằng này mà sa đà vào việc đếm thành phần như Interface thì tất cả method ko có nội dung hay Abstract thì có state thì bạn sẽ rơi vào vòng luẩn quẩn, học như thế rất mệt mỏi và sẽ rất rối.

1. Tổng quan

Điểm khác biệt cốt lõi cửa 2 thằng này đến từ tư tưởng sử dụng, ko phải đến từ việc thằng này có abc, thằng kia có xyz.

  • Interface giống như 1 bản hợp đồng (contract), tất cả các class implementation của nó phải tuân theo bản hợp đồng đấy. Vì sao lại là contract thì đọc tiếp bên dưới.
  • Abstract class là dùng để thừa kế, mối quan hệ cha-con. Tất cả các class con sẽ được thừa kế những gì của class cha

Nếu nhìn vào điểm khác nhau bạn có thể sẽ nghĩ là “2 thứ nó khác nhau rõ ràng như thế này, sao người ta lại đặt ra câu hỏi là phân biệt 2 thứ này nhỉ?”. Tuy nhiên trên thực tế, nhất là trong Java, về mặt functional thì Interface và Abstract class ko khác nhau nhiều. Sau khi bản update ở Java 8, thì Interface và Abstract class lại càng giống nhau hơn.

Nếu bạn so sánh 2 thằng này mà sa đà vào việc đếm thành phần như Interface thì tất cả method ko có nội dung hay Abstract thì có state thì bạn sẽ rơi vào vòng luẩn quẩn, học như thế rất mệt mỏi và sẽ rất rối.

2. Thế nào là contract?

Về ý nghĩa nói chung, interface trong lập trình như là cách giao tiếp giữa các component, nó ẩn phần implementation. Lấy 1 ví dụ đời thường, coi như chuẩn TypeC kết nối giữa máy tính và màn hình là 1 interface.

  • Máy tính là Client
  • Interface là TypeC
  • Màn hình Dell, màn hình HP, màn hình ThinkPad là Implementation của Interface

TypeC định nghĩa là tất cả các màn hình mà có theo chuẩn TypeC thì đều phải có 2 method là: âm thanh sound() và hình ảnh display(), để khi máy tính kết nối vào bất kỳ cái màn hình nào cũng sẽ gọi được 2 method này. Contract ở đây là hợp đồng giữa client và interface. Nhiệm vụ của interface lúc này là sẽ force (ép buộc) tất cả các implementation phải tuân theo bản hợp đồng đó –> compile error nếu implementation nào ko override method của interface.

3. Chỗ nào cho Abstract class?

Thông thường, nếu 2 class có những điểm chung về code thì ta sẽ viết các điểm chung đó vào class cha và viết điểm riêng vào 2 class con.

Giả sử cả 3 Implementation ở ví dụ trên đều có phần code method sound() là giống nhau, thì tốt nhất là ta nên chuyển method sound lên Abstract class.

  • Vì Abstract class phải implement interfact TypeC, do đó nó phải implement cả 2 method sound() và display(), nhưng nó lại ko muốn implement method display() vì đây là phần riêng của mỗi implementation nên ở nó sẽ đánh dấu method này là abstract, những class con phải tự override.
  • Do thằng class cha này có 1 method dạng abstract –> class cha này ko phải là 1 thực thể, nó chỉ là 1 thằng cha ảo và nó ở trạng thái imcomplete (có method abstract – ko có nội dung của method), để tránh side effect, java force (bắt buộc) phải có keyword abstract chỗ class để client ko thể khởi tạo nhầm.

Bạn có thể sẽ nhìn thấy cái pattern này ở trong nhiều thư viện khác nhau và giờ chắc bạn đã hiểu vì sao ở các thư viện, nó cho phép mình viết custom implementation thì người ta thường hướng dẫn bạn nên extend từ Abstract class thay vì implement trực tiếp từ Interface.

Nếu bạn vẫn chưa hiểu vì sao thì đây là câu trả lời:

  • Interface trong các thư viện thường được extend từ 1 vài interface khác nên nó thường có rất nhiều method. Nếu mình implement trực tiếp từ các Interface đó thì mình sẽ phải đọc rất nhiều các defined implementation của ngta để biết phải viết cái gì.
  • Tuy nhiên, nếu mình extend từ Abstract class thì mình chỉ phải implement 1 hoặc 2 methods thôi, như thế dễ cho mình hơn.