1. Tính trừu tượng trong Java là gì?

Trừu tượng trong thực tế là ảo và không có thật. Thực ra trong lập trình thì trừu tượng vẫn có thật và tồn tại. Tính trừu tượng trong Java thực chất là tính chất không thể hiện cụ thể mà chỉ nêu tên vấn đề. Đó là một quá trình che giấu các hoạt động bên trong và chỉ hiển thị những tính năng thiết yếu của đối tượng tới người dùng.

Hay hiểu đơn giản nó là một tiến trình ẩn các cài đặt chi tiết và chỉ hiển thị tính năng tới người dùng. Nó chỉ hiển thị các thứ quan trọng tới người dùng và ẩn các chi tiết nội tại. Sử dụng tính trừu tượng giúp chúng ta chỉ tập trung vào trọng tâm thay vì quan tâm đến cách nó thực hiện. Java trừu tượng hóa thông qua các lớp trừu tượng Abstract class và các giao diện Interface .

2. Lớp trừu tượng trong Java

Một lớp trừu tượng là một lớp mà không được khởi tạo. Tất cả các chức năng khác của lớp vẫn tồn tại, và tất cả các trường, phương thức, và hàm khởi tạo đều được truy cập với một cách giống nhau. Ta không thể tạo một đối tượng với một lớp trừu tượng hóa. Nếu một lớp là lớp trừu tượng và nó không được khởi tạo, lớp này không được sử dụng trừ khi nó là lớp con.

Mục đích lớp trừu tượng là tạo ra lớp chung cho những lớp có liên quan với nhau kế thừa. Ví dụ khi xây dựng phần mềm quản lý nhà trường: Những lớp sinh viên, giảng viên, cán bộ,… có những thuộc tính và phương thức chung như tên, năm sinh, quê quán,… thì ta sẽ tạo một lớp con người là lớp trừu tượng và những đặc điểm chung được để trong lớp chung. Khi phát triển chương trình, ta chỉ có thể tạo các đối tượng từ lớp con kế thừa lớp chung này. Không thể cho tạo đối tượng từ lớp chung này được

Trong Java, chúng ta chỉ sử dụng từ khóa abstract để khai báo một class trừu tượng. Cú pháp như sau:

abstract class tên_class{
   //code     
}

Nếu cố gắng tạo ra các đối tượng của một class trừu tượng, chúng ta sẽ bị lỗi biên dịch. Ví dụ như:

Animal a1 = new Animal()

Lỗi kiểu như này sẽ hiển thị ra:

Animal is abstract; cannot be instantiated

3. Phương thức trừu tượng trong Java

Thực ra lý ro để khai báo một lớp trừu tượng là vì trong lớp có ít nhất một phương thức trừu tượng. Hay hiểu đơn giản là việc một lớp có ít nhất một phương thức được định nghĩa là trừu tượng thì lớp đó phải khai báo trừu tượng. Phương thức có định nghĩa từ khóa abstract khi khai báo là phương thức trừu tượng.

Cú pháp : [access_modifier] abstract [kiểu_trả_về] [tên_phương_thức_trừu_tượng] [<đối_số_truyền_vào>];

Trong đó:

  • [access_modifier] là phạm vi truy cập của phương thức trừu tượng. Phạm vi truy cập của phương thức trừu tượng tương tự như của các phương thức bình thường nhưng không được khai báo phạm vi truy cập là private, nếu để là private thì trình biên dịch sẽ báo lỗi.
  • [kiểu_trả_về] là kiểu dữ liệu của phương thức.
  • [tên_phương_thức_trừu_tượng] phải tuân theo quy tắc đặt tên phương thức (hàm) của Java. Phương thức này có thể có hoặc không có <đối_số_truyền_vào>.

Ví dụ:

abstract class Fruits
{
  abstract void taste(); //abstract method
}
class Apple extends Fruits {
  @Override
  void taste() {
    System.out.println("Sweet taste");
    
  }
  
}
public class AbstractDemo {
  public static void main(String[] args) {
    Apple a = new Apple();
    a.taste();
  }
}

Kết quả

Sweet taste
Sour taste

Đặc điểm của các phương pháp trừu tượng đó là:

  • Chúng ta chỉ có thể sử dụng các phương thức trừu tượng bên trong một lớp trừu tượng.
  • Phương thức trừu tượng không có bất kỳ mã nào trong thân phương thức.
  • Chúng ta phải sử dụng từ khóa trừu tượng để khai báo một phương thức trừu tượng.

Lưu ý

Để sử dụng phương thức trừu tượng này, chúng ta cần phải ghi đè (override) nó trong lớp con kế thừa trực tiếp lớp khai báo phương thức này.

4. Các hàm tạo lớp trừu tượng trong Java

Lớp trừu tượng cũng hỗ trợ các hàm tạo. Chúng ta có thể sử dụng các hàm tạo được tham số hóa hoặc mặc định. JVM ngầm gọi các hàm tạo mặc định như chúng ta đã thấy trong kế thừa.

Trong ví dụ sau ta sẽ sử dụng các hàm tạo được tham số hóa trong lớp trừu tượng. Chúng ta gọi hàm tạo này từ hàm tạo lớp con bằng cách sử dụng từ khóa super . Khi phương thức khởi tạo của lớp con được gọi trong quá trình tạo đối tượng, nó sẽ gọi phương thức khởi tạo

abstract class Fruits
{
  String fruitname;
  String color;
  
  Fruits(String color) {
    this.color = color;
    System.out.println("Fruits constructor");
  }
  //abstract method
  abstract void taste();
  
  //non-abstract method
  public void getFruitName(String fruit ) {
    this.fruitname = fruit;
  }
}
class Apple extends Fruits {
  Apple(String color) {
    super(color);
    System.out.println("Apple constructor");
  }
  @Override
  void taste() {
    System.out.println("Sweet taste");
    
  }
  
}
public class AbstractDemo {
  public static void main(String[] args) {
    Apple a = new Apple("red");
    a.getFruitName("Apple");
    System.out.println("Fruit name: " + a.fruitname);
    System.out.println("Fruit color: " + a.color);
    a.taste();
  
  }
}

Kết quả

Fruits constructor
Apple constructor
Fruit name: Apple
Fruit color: red
Sweet taste

5. Sự khác biệt giữa lớp trừu tượng và giao diện Interface

Ta có thể so sánh giữa lớp trừu tượng và Interface qua bảng sau

Lớp trừu tượng Interface
Lớp trừu tượng có thể có cả phương thức trừu tượng và không trừu tượng Chỉ có thể có các phương thức trừu tượng. Từ Java 8, hỗ trợ các phương thức mặc định
Không hỗ trợ đa kế thừa Hỗ trợ đa kế thừa
Sử dụng từ khóa trừu tượng Sử dụng từ khóa giao diện
Sử dụng từ khóa kéo dài để kế thừa lớp trừu tượng Sử dụng từ khóa triển khai để triển khai giao diện
Nó có thể mở rộng một lớp Java khác và cũng có thể triển khai giao diện Nó chỉ có thể mở rộng giao diện khác
Các thành viên có thể có các công cụ sửa đổi quyền truy cập như riêng tư, được bảo vệ,… Thành viên chỉ có thể công khai
Nó có thể có các biến tĩnh, không tĩnh, cuối cùng hoặc không cuối cùng. Nó chỉ có thể có các biến tĩnh và biến cuối cùng