So sánh interface và abstract class năm 2024
Trong bài này, tôi sẽ giới thiệu về lớp trừu tượng (abstract class) và interface trong Java, đồng thời phân tích sự giống và khác nhau giữa chúng. Show
Các tính chất của lập trình hướng đối tượng, các bạn có thể xem ở bài viết: 4 tính chất của lập trình hướng đối tượng trong Java. Nội dung Đặc điểm của lớp trừu tượng (abstract class)Một lớp được khai báo với từ khóa abstract là lớp trừu tượng (abstract class). Lớp trừu tượng có thể có các phương thức abstract hoặc non-abtract. Lớp trừu tượng có thể khai báo 0, 1 hoặc nhiều method trừu tượng bên trong. Không thể khởi tạo 1 đối tượng trực tiếp từ một class trừu tượng. Một lớp kế thừa từ lớp trừu tượng (subclass – lớp con) không cần phải implement non-abstract methods, nhưng những method nào có abstract thì bắt buộc phải override. Trừ khi subclass cũng là abstract. Cú pháp: Phương thức trừu tượng trong Java
Cú pháp: Ví dụ về lớp trừu tượng và phương thức trừu tượngVí dụ: Viết chương trình vẽ một hình bất kỳ với màu đỏ, sao cho cách sử dụng là giống nhau, bất kể đó là hình gì. Hình đó có thể là hình chữ nhật (rectangle), hình tròn (circle), tam giác (triangle), đường (line), … Với yêu cầu trên, tôi tạo một lớp trừu tượng Shape. Lớp này cung cấp một phương thức trừu tượng draw, phương thức này để đảm bảo rằng tất cả các hình đều có cùng cách sử dụng (draw). Ngoài ra, có phương thức không trừu tượng getColor để cung cấp màu sử dụng chung cho tất cả các hình. Tiếp theo, tôi tạo 2 lớp Rectangle và Circle kế thừa từ lớp Shape, 2 lớp này có những cách xử lý draw khác nhau. Cuối cùng, tôi tạo class ShapeApp, gọi phương thức draw để vẽ hình theo yêu cầu. Shape.java public abstract class Shape { private String color = "red"; public Shape() { } public abstract void draw(); public String getColor() { }
}Rectangle.java public class Rectangle extends Shape { @Override public void draw() { }
}Circle.java public class Circle extends Shape { @Override public void draw() { }
}ShapeApp.java public class ShapeApp { public static void main(String[] args) { }
}Kết quả: Draw red rectangle Draw red circle Một vài lưu ýLớp con bắt buộc phải cài đặt (implement) tất cả các phương thức trừu tượng của lớp cha Bạn nhận được thông báo lỗi nếu lớp con không cài đặt (implement) tất cả các phương thức trừu tượng của lớp cha: The type Triangle must implement the inherited abstract method Shape.draw(). Không thể khởi tạo trực tiếp một lớp trừu tượng Bạn nhận được thông báo lỗi khi cố tình khởi tạo một lớp trừu tượng: Cannot instantiate the type Shape. Interface trong JavaĐặc điểm của Interface
Một interface tương tự với một class bởi những điểm sau đây:
Một interface khác với một class ở một số điểm sau đây:
Ví dụ sử dụng Interface trong JavaTương tự như yêu cầu ở ví dụ về sử dụng abstract class ở trên, nhưng tôi sẽ dụng Interface để áp dụng vào chương trình. Shape.java public interface Shape { String color = "red"; void draw(); } Rectangle.java public class Rectangle implements Shape { @Override public void draw() { }
}Circle.java public class Circle implements Shape { @Override public void draw() { }
}ShapeApp.java public class ShapeApp { public static void main(String[] args) { }
}Kết quả: Draw red rectangle Draw red circle Khi ghi đè các phương thức được định nghĩa trong interface, có một số qui tắc sau:
Khi triển khai interface, có vài quy tắc sau:
Đa thừa kế trong Java bởi InterfaceNếu một lớp triển khai đa kế thừa, hoặc một Interface kế thừa từ nhiều Interface thì đó là đa kế thừa. Trong Java, một lớp chỉ được thừa kế (extends) từ một lớp, có thể cài đặt (implements) nhiều interface. Tuy nhiên, một interface có thể thừa kế (extends) nhiều interface. Một interface không thể cài đặt (implements) interface khác, do interface không phần cài đặt, chỉ chứa các khai báo. Ví dụ một lớp cài đặt (implements) nhiều interface: 2 Ví dụ interface kế thừa (extend) nhiều interface 3 Câu hỏi: Đa kế thừa không được hỗ trợ thông qua lớp trong Java nhưng là có thể bởi Interface, tại sao? Như đã giới thiệu, kế thừa không được hỗ trợ thông qua lớp. Nhưng nó được hỗ trợ bởi Interface bởi vì không có tính lưỡng nghĩa khi trình triển khai được cung cấp bởi lớp Implementation. Ví dụ đa thừa kế với Interface 4 Trong ví dụ trên, interface Printable và Showable có cùng các phương thức print() nhưng trình triển khai của nó được cung cấp bởi lớp InterfaceDemo, vì thế không có tính lưỡng nghĩa ở đây. Ví dụ đa thừa kế với class 5 Trong ví dụ trên, lớp Printable và Showable có cùng các phương thức print() và InterfaceDemo kế thừa 2 class đó không override lại phương thức print() nên trình biên dịch không biết thực thi phương thức print() của lớp Printable hay là của lớp Showable. Để đảm bảo an toàn và giảm tính phức tạp của hệ thống nên Java không hỗ trợ đa thừa kế đối với class. Marker (hay Tagging) Interface trong Java là gì?Đó là một Interface mà không có thành viên nào. Ví dụ: Serializable, Cloneable, Remote, … Chúng được sử dụng để cung cấp một số thông tin thiết yếu tới JVM để mà JVM có thể thực hiện một số hoạt động hữu ích. Ví dụ 6 Có hai mục đích thiết kế chủ yếu của tagging interface là:
Interface lồng nhau trong JavaMột Interface có thể có Interface khác, đó là lồng Interface. Ví dụ: 7 So sánh abstract class và interface trong JavaLớp trừu tượng (abstract class)InterfaceThể hiện tính trừu tượng < 100%Thể hiện tính trừu tượng 100% (Java < 8).Lớp trừu tượng có thể có các phương thức abstract và non-abstractPhiên bản Java < 8, Interface chỉ có thể có phương thức abstract. Phiên bản Java 8, có thể thêm default và static methods. Phiên bản Java 9, có thể thêm private methods.Lớp trừu tượng không hỗ trợ đa kế thừaInterface hỗ trợ đa kế thừaLớp trừu tượng có thể có các biến final, non-final, static và non-staticInterface chỉ có các biến static finalLớp trừu tượng có thể có phương thức static, phương thức main và constructorInterface không thể có phương thức static, main hoặc constructor.Từ khóa abstract được sử dụng để khai báo lớp trừu tượngTừ khóa interface được sử dụng để khai báo InterfaceLớp trừu tượng có thể cung cấp trình triển khai của InterfaceInterface không cung cấp trình triển khai cụ thể của lớp abstractVí dụ: public abstract class Shape { public abstract void draw(); }Ví dụ: public interface Drawable { void draw(); }Sử dụng Abstract class khi chúng ta chỉ có thể hoàn thành một vài chức năng (method/ function) chuẩn của hệ thống, một vài chức năng còn lại các lớp extends phải hoàn thành. Những tính năng đã hoàn thành này vẫn sử dụng như bình thường, đây là những tính năng chung.Sử dụng Interface khi bạn muốn tạo dựng một bộ khung chuẩn gồm các chức năng (method/ function) mà tất cả module/ project cần phải có. Các module phải implements tất cả chức năng đã được định nghĩa. Nói về Abtract Class và Interface, đôi khi bạn sẽ gặp một số cách gọi: Khi một class extend một class/ abtract class thì có nghĩa là ta đang thể hiện mối quan hệ is-a (là), còn khi implement một interface, thì ta đang thể hiện mối quan hệ has-a (có, hay thực hiện). |