Abstract Class là gì?

04-06-2024


Trong Java, abstract class là một trong những khái niệm quan trọng trong lập trình hướng đối tượng (OOP). Abstract class cung cấp một cách để định nghĩa các lớp mà từ đó các lớp con có thể kế thừa, nhưng không thể khởi tạo trực tiếp. Trong bài viết này, chúng ta sẽ tìm hiểu về abstract class, cách sử dụng nó và cung cấp nhiều ví dụ minh họa để bạn có thể nắm bắt được cách áp dụng nó trong thực tế.

Abstract class là một lớp trừu tượng, tức là không thể tạo ra các đối tượng từ nó. Nó chỉ được sử dụng để định nghĩa các thuộc tính và phương thức chung cho các lớp con kế thừa từ nó.

Để khai báo một abstract class trong Java, ta sử dụng từ khóa abstract trước từ khóa class, như sau:

abstract class Animal {
    // các thuộc tính và phương thức
}

Abstract Class khai báo một hay nhiều method trừu tượng. Chúng có thể có cả method trừu tượng và method cụ thể. Một lớp bình thường không thể có method trừu tượng. Điều này có nghĩa là một abstract class phải chứa ít nhất một method trừu tượng. 

Một method trừu tượng là một method được khai báo không có triển khai (không có dấu ngoặc nhọn và kết thúc là một dấu chấm phẩy).

abstract class Animal {
    // Một phương thức trừu tượng
    abstract void makeSound();
    
    // Một phương thức không trừu tượng
    void sleep() {
        System.out.println("Sleeping...");
    }
}

Một Abstract Class không thể tạo đối tượng nhưng có thể có các lớp con. Khi một lớp trừu tượng có các lớp con, các lớp con thường cung cấp triển khai cho tất cả các phương thức trừu tượng của lớp cha. Tuy nhiên, nếu lớp con không triển khai các phương thức của lớp cha, nó cũng sẽ trở thành một lớp trừu tượng. Và vì được kế thừa như vậy nên Abstract class không thể được đánh dấu là final

// Một lớp con của Animal
class Dog extends Animal {
    // Triển khai phương thức trừu tượng makeSound
    @Override
    void makeSound() {
        System.out.println("Woof Woof");
    }
    
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "Buddy";
        dog.makeSound(); // Gọi phương thức đã triển khai
        dog.sleep();     // Gọi phương thức không trừu tượng
        
        Animal.numberOfLegs = 4;
        System.out.println("Number of legs: " + Animal.numberOfLegs);
    }
}

Nếu bạn cố tình tạo 1 đối tượng từ abstract class bạn sẽ nhận được 1 lỗi.

Animal animal = new Animal(); // Lỗi biên dịch: Animal is abstract; cannot be instantiated

Khi Nào Nên Sử Dụng Abstract Class

Sử dụng abstract class khi:

  • Bạn muốn định nghĩa một lớp cơ sở mà các lớp con sẽ kế thừa.
  • Bạn có một số phương thức mà bạn muốn bắt buộc các lớp con phải triển khai.
  • Bạn muốn cung cấp một số triển khai mặc định cho các phương thức nhưng vẫn muốn lớp con có thể ghi đè

Lợi ích của việc sử dụng abstract class trong Java

Sử dụng abstract class trong Java có nhiều lợi ích, bao gồm:

Tính tái sử dụng code

Một trong những lợi ích chính của abstract class là tính tái sử dụng code. Với việc định nghĩa các thuộc tính và phương thức chung trong abstract class, ta có thể sử dụng lại chúng trong các lớp con kế thừa từ nó, giúp giảm thiểu việc viết lại code và tăng tính hiệu quả của chương trình.

Giảm thiểu sự phụ thuộc giữa các lớp

Khi sử dụng abstract class, ta có thể giảm thiểu sự phụ thuộc giữa các lớp. Thay vì kế thừa từ nhiều lớp khác nhau, ta chỉ cần kế thừa từ một abstract class và triển khai các phương thức của nó. Điều này giúp giảm thiểu sự rắc rối và tăng tính linh hoạt của chương trình.

Tính đa hình

Abstract class cũng cho phép ta sử dụng tính đa hình trong lập trình hướng đối tượng. Tức là các lớp con có thể triển khai các phương thức abstract theo cách khác nhau, tùy thuộc vào nhu cầu của từng lớp con. Điều này giúp tăng tính linh hoạt và tính tái sử dụng code của chương trình.

Ví dụ chi tiết về khai báo Abstract class và kế thừa

File: Shape.java

public abstract class Shape {
    public abstract double getArea();
    public abstract double getPerimeter();
}
File: Circle.java
public class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }
}

File: Rectangle.java

public class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double getArea() {
        return width * height;
    }

    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
}
File: TestShape.java

public class TestShape {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);

        System.out.println("Circle area: " + circle.getArea()); // Output: Circle area: 78.53981633974483
        System.out.println("Circle perimeter: " + circle.getPerimeter()); // Output: Circle perimeter: 31.41592653589793

        System.out.println("Rectangle area: " + rectangle.getArea()); // Output: Rectangle area: 24.0
        System.out.println("Rectangle perimeter: " + rectangle.getPerimeter()); // Output: Rectangle perimeter: 20.0
    }
}

Trong ví dụ này, Shape là một abstract class với hai phương thức abstract getArea và getPerimeter. Các lớp Circle và Rectangle kế thừa từ Shape và triển khai các phương thức này.

Abstract class là một công cụ mạnh mẽ trong Java để tạo ra các cấu trúc kế thừa phức tạp. Nó giúp bạn định nghĩa các phương thức mà các lớp con phải triển khai, đồng thời cung cấp các phương thức mặc định mà lớp con có thể sử dụng. Hiểu và sử dụng đúng abstract class sẽ giúp bạn xây dựng các ứng dụng Java linh hoạt và dễ bảo trì. hy vọng rằng bài viết trên đây đã cung cấp cho bạn một cái nhìn đầy đủ hơn về Abstract Class là gì.