Trong Java, một abstract class (lớp trừu tượng) là một lớp không thể được khởi tạo trực tiếp và thường được sử dụng như một lớp cơ sở cho các lớp con kế thừa. Nó cung cấp một khung sườn cho các lớp con, trong đó một số phương thức có thể được triển khai (implemented) trong lớp cha, trong khi các phương thức khác sẽ phải được các lớp con triển khai cụ thể.
Abstract class rất hữu ích khi bạn muốn cung cấp một số phương thức hoặc thuộc tính chung cho nhiều lớp con, nhưng đồng thời, muốn các lớp con có thể cung cấp phần triển khai cụ thể cho các hành vi khác.
Ví dụ:
abstract class Animal { // Phương thức trừu tượng (không có phần thân) abstract void sound(); // Phương thức cụ thể (có phần thân) void sleep() { System.out.println("This animal is sleeping."); } }
Một abstract class không thể được tạo đối tượng trực tiếp. Bạn chỉ có thể sử dụng lớp con của abstract class để khởi tạo đối tượng.
Ví dụ:
Animal animal = new Animal(); // Lỗi biên dịch
Thay vào đó, bạn phải tạo một lớp con kế thừa abstract class đó, sau đó khởi tạo lớp con này:
class Dog extends Animal { void sound() { System.out.println("Dog barks"); } } Dog dog = new Dog(); // Đúng
Mặc dù không thể khởi tạo trực tiếp, nhưng abstract class vẫn có thể có constructor. Constructor này có thể được các lớp con gọi để khởi tạo các thuộc tính chung.
Ví dụ:
abstract class Animal { String name; // Constructor Animal(String name) { this.name = name; } abstract void sound(); } class Dog extends Animal { Dog(String name) { super(name); } void sound() { System.out.println(name + " barks"); } }
Trong Java, một lớp chỉ có thể kế thừa từ một abstract class duy nhất. Điều này giúp tránh sự phức tạp của kế thừa đa hình mà Java không hỗ trợ đối với các lớp.
Ví dụ:
class Dog extends Animal { // Đúng } class Cat extends Animal { // Đúng } class Hybrid extends Dog, Cat { // Sai: Java không hỗ trợ kế thừa đa hình với các class }
Bạn nên sử dụng abstract class khi:
Ví dụ: Nếu bạn có một lớp cơ sở là Animal và muốn tất cả các động vật đều có thể ngủ, nhưng cách phát ra âm thanh sẽ khác nhau tùy theo từng loại động vật, thì bạn có thể định nghĩa abstract class Animal với một phương thức sleep() cụ thể và một phương thức sound() trừu tượng.
abstract class Animal { abstract void sound(); // Phương thức trừu tượng (lớp con phải triển khai) void sleep() { System.out.println("This animal is sleeping."); } } class Dog extends Animal { void sound() { System.out.println("Dog barks"); } } class Cat extends Animal { void sound() { System.out.println("Cat meows"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.sound(); // Output: Dog barks dog.sleep(); // Output: This animal is sleeping. Cat cat = new Cat(); cat.sound(); // Output: Cat meows cat.sleep(); // Output: This animal is sleeping. } }
Abstract class là một công cụ quan trọng trong lập trình hướng đối tượng để cung cấp một lớp cơ sở với cả phương thức trừu tượng và phương thức cụ thể. Nó giúp giảm bớt việc lặp lại mã và cho phép các lớp con tập trung vào việc triển khai các hành vi cụ thể.
Abstract class thường được sử dụng khi bạn có một số hành vi chung mà tất cả các lớp con cần có, và bạn muốn cung cấp phần triển khai chung đó, đồng thời buộc các lớp con triển khai một số hành vi khác một cách cụ thể.