Tại sao cần sử dụng Interface khi đã có Abstract class?

Em hỏi ngu tí ạ. Tại sao cần sử dụng interface. Ngoài cái đa kế thừa ra thì nó có tác dụng gì hơn abstract class đâu ạ. Abstract thì nó thêm phương thức non abstract thôi. Còn nếu chỉ có abstract method thì có khác gì đâu ạ. Em mới tìm hiểu nên hơi mơ hồ, cũng xem nhiều ví dụ rồi nhưng đều không nói rõ được vấn đề. Topic em lập hơi lộn xộn các anh thông cảm.

Ví dụ nhé : bạn muốn tạo ra một Sở Thú, bạn nhận thấy chúng có nhiều điểm chung, như có tên, có tiếng “kêu”. Đó là điểm chung của tất cả các loài động vật ==> Tạo một abstract class Animal. Tuy nhiên lại có một số loài lại biết bay, một số loài lại biết bơi. Chú ý là ở đặc điểm biết bay hay biết bơi chỉ có ở một số loài, chứ không phải có ở tất cả các loài ==> Ta không thể để thuộc tính bơi hay bay trong abstract class Animal mà phải tạo ra 2 Interface khác nhau là Can_FlyCan_Swim rồi xem class nào có thể implements từng cái thích hợp.
VD:
class Fish extends Animal implements Can_Swim
class Bird extends Animal implements Can_Fly

7 Likes

Phân biệt tác dụng của interface và abstract khác nhau nha bạn.

Interface có tác dụng thêm vào một chức năng ở bất kỳ class nào. Ví dụ như person class sẽ có interface IRun, IEat, ILearn… thường người ta sẽ nói sub class thực hiện interface(chức năng)

Abstract có tác dụng như một lớp cha cho tất cả các lớp con có cùng bản chất. Ví dụ như Animal class sẽ có các property chung, phương thức chung. sub class sẽ kế thừa abstract

7 Likes

Abstract class có chức năng tương tự như interface. Bạn không thể khởi tạo đối tượng được khai báo từ abtract class và interface, và cũng có thể tồn tại 2 loại method khác nhau: có implemetation hoặc không có implementation.

Tuy nhiên, với abstract class, bạn có thể định nghĩa field thuộc kiểu staticfinal, định nghĩa public, protectedprivate. Với interface, tất cả các field đều là public, static, final, và tất cả method bạn khai báo (declare) hay định nghĩa (define) (theo default method) đều public.

Vậy khi nào sử dụng abstract class, khi nào sử dụng interface?

Bạn có thể sử dụng abstract class nếu thoả một trong các điều kiện sau đây:

  • Bạn muốn chia sẻ (share) đoạn code trùng nhau giữa các class liên quan (related classes).
  • Bạn nhận thấy các class thừa kế từ abstract class có nhiều method và field giống nhau, và access modifier gắn liền với các method, field đó không phải là public (protected hoặc private).
  • Bạn muốn khai báo các field là non-static hoặc non-final. Cách này giúp bạn có thể định nghĩa các method có thể truy cập và thay đổi state của object.

Bạn có thể sử dụng interface nếu thoả một trong các điều kiện sau đây:

  • Các class không liên quan với nhau (unrelated classes) khi implement từ interface. Ví dụ, interface ComparableCloneable được hiện thực bởi nhiều class không liên quan.
  • Bạn chỉ quan tâm đến hành động (behavior) của một kiểu dữ liệu nào đó (data type), nhưng lại không cần nhắc đến các hiện thực (implementation) hành động đó như thế nào.
  • Bạn muốn tận dụng cơ thế multiple inheritance.

Một ví dụ về abstract class là AbstractMap, là 1 class trong Collections Framework. Nó có các subclasses như HashMap, TreeMap, ConcurrrentHashMap, cùng có chung nhiều method giống nhau, như: get, put, isEmpty, containsKey, containsValue.

Một ví dụ về interface là HashMap. HashMap implements từ các interface Serializable, Cloneable, Map<K, V>. Bằng các đọc Javadocs của các interface, bạn có thể nhận biết được object của HashMap có thể clone, có serializable (chuyển object sang byte stream, chuyển byte stream sang object), và có chức năng của map. Interface Map<K, V> được mở rộng mới nhiều default method như mergeforEach mà các class hiện thực có thể sử dụng mà không cần định nghĩa.

Ví dụ về HashMap cũng là cách sử dụng abstract class và interface trong một library và framework. Class HashMap vừa imlements một số interfaces, vừa thừa kế từ abstract class AbstractMap

https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

10 Likes

implement không phải là kế thừa mà là đính kèm
Abstract class là class, trong khi interface là “tập hợp các thuộc tính”. Hiểu được “kế thừa” và “đính kèm” khác nhau thế nào, bạn sẽ hiểu tại sao lại sinh ra 2 thứ khác nhau.

5 Likes

Không chính xác nha. Bản chất interface vẫn là kế thừa thôi.

Class, Abstract hay Interface nói gì thì nói. Cả 3 đêu là class.
Chúng ta đều biết 1 class gồm có những gì và chúng ta có thể mô tả 1 class như 1 Abstract hay 1 Interface dựa theo khái niệm của chúng.
Xét 1 môi trường nhỏ: bao gồm 1 vài động vật như thỏ, chim, sói

  • Cả 3 đều là động vật, đều có thể di chuyển, ăn, trú ẩn. Nhưng thỏ có thể nhảy, đi trong khi đó chim có thể bay, đi và sói chạy, đi. Ở đây, nếu ta tưởng tưởng (abstract) rằng 1 vài động vật bao gồm nhiều loài hơn nhưng đều có thể di chuyển, ăn, trú ẩn. Như vậy ta sẽ có 1 lớp Abstract Animal.
  • Rõ ràng cả 3 động vật kể trên có những phương thức riêng mặc cho chúng cùng 1 lớp Animal. Vậy xây dựng method riêng cho chúng thôi.
  • Nếu cứ xây dựng 3 lớp động vật như này thì cả 3 đều độc lập, riêng biệt. Nhưng cho dù là thế cả 3 đều có thể tác động lẫn nhau, sói ăn thịt thỏ, thỏ sợ sói và nếu trong môi trường này còn có thêm những lớp động vật khác thì sao? Chúng sẽ giao tiếp với nhau ra sao? Thêm phương thức vào lớp Animal để lớp con override ư?
  • Được, Chúng ta có thể xây dựng như thế. Nhưng nếu 1 lớp mà lớp này không thuộc lớp Animal như thời tiết, bệnh tật thì sao nhỉ? :slight_smile: Chắc chắn là không.
  • Xây dựng cho những lớp mới toanh như thời tiết, bệnh tật thế chúng giao tiếp với đối tượng thuộc Animal như thế nào? Đa kế thừa sẽ giải quyết vấn đề này. Tạo ra 1 lớp không constructor chỉ khai báo tên phương thức để lớp con override những method, và như vậy chúng ta có 1 hệ sinh thái mà có những lớp có thể giao tiếp nhau nhưng có những lớp không thể giao tiếp được.
    Thường thì lớp Interface ít gặp, toàn gặp trong nhưng chương trình lớn thôi.
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?