"Xin chào, Amigo! Chúng ta có một chủ đề mới hấp dẫn."

"Hôm nay chỉ là một ngày của những chủ đề hấp dẫn!"

"Tại sao, cảm ơn bạn!"

"Không có gì."

"Bạn có nhớ khi chúng tôi giới thiệu lớp cơ sở ChessItem để đơn giản hóa tất cả các lớp cho quân cờ không?"

"Đúng."

"Bây giờ hãy tưởng tượng rằng mỗi mảnh có một phương thức xử lý hiển thị mảnh trên màn hình. Bạn gọi phương thức đó và mảnh sẽ tự vẽ theo tọa độ hiện tại của nó. Có hữu ích không khi di chuyển phương thức này vào lớp cơ sở?"

"Đúng." Sau khi tôi đã học về tính đa hình, tôi có thể gọi phương thức kết xuất cho tất cả các phần, bất kể loại của chúng. Một cái gì đó như thế này: "

Ví dụ:
class ChessBoard
{
  public void drawAllChessItems()
  {
  //draw them regardless of their type.
  ArrayList <ChessItem> items = new ArrayList<ChessItem>();
  items.add(new King());
  items.add(new Queen());
  items.add(new Bishop());

  //draw them regardless of their type.
  for (ChessItem item: items)
  {
   item.draw();
  }
 }
}

"Làm tốt lắm. Chính xác. Và điều gì sẽ được thực hiện bằng phương thức rút thăm của chính lớp ChessItem?"

"Tôi không biết. Cờ vua không có quân cờ như vậy. Và điều đó có nghĩa là nó không có hình ảnh đại diện."

"Chính xác. Và không có ý nghĩa gì khi tạo một đối tượng ChessItem. Không có quân cờ nào như vậy. Nó chỉ là một lớp trừu tượng —một lớp mà chúng tôi tạo ra để thuận tiện. Đó là cách tính trừu tượng hoạt động trong OOP: chúng tôi đã di chuyển tất cả (được chia sẻ) quan trọng bởi tất cả các quân) dữ liệu và phương thức vào một lớp cơ sở , nhưng chúng tôi giữ sự khác biệt của chúng trong các lớp tương ứng với các quân cờ cụ thể."

Java có một loại lớp đặc biệt cho việc này: lớp trừu tượng . Dưới đây là ba điều cần nhớ về các lớp trừu tượng.

1) Một lớp trừu tượng có thể khai báo các phương thức mà không cần triển khai chúng. Một phương pháp như vậy được gọi là một phương pháp trừu tượng.

Ví dụ:
 public abstract class ChessItem
{
 public int x, y; //coordinates
 private int value; //the piece's "value"

 public int getValue() //an ordinary method, returns value
 {
   return value;
 }

 public abstract void draw(); //abstract method. There is no implementation.

}

2) Một phương thức trừu tượng được đánh dấu bằng từ khóa trừu tượng .

Nếu một lớp thậm chí có một phương thức trừu tượng, thì lớp đó cũng được đánh dấu bằng trừu tượng .

3) Bạn không thể tạo các đối tượng của một lớp trừu tượng. Mã cố gắng làm như vậy sẽ không được biên dịch.

mã Java Sự miêu tả
ChessItem item = new ChessItem();
item.draw();
Mã này sẽ không được biên dịch.
ChessItem item = new Queen();
item.draw();
Nhưng bạn có thể làm điều này.

4) Nếu lớp của bạn kế thừa một lớp trừu tượng, bạn cần ghi đè tất cả các phương thức trừu tượng được kế thừa, tức là bạn phải triển khai chúng. Nếu không, lớp của bạn cũng sẽ phải được khai báo trừu tượng. Nếu lớp thậm chí có một phương thức chưa được thực hiện được khai báo trực tiếp trong lớp hoặc được kế thừa từ lớp cha, thì lớp đó được coi là trừu tượng.

"Nhưng tại sao tất cả những điều này lại cần thiết? Tại sao chúng ta cần các lớp trừu tượng? Thay vào đó, không thể sử dụng các lớp thông thường sao? Và thay vì các phương thức trừu tượng, chúng ta không thể tạo các triển khai trống bao gồm mở và đóng dấu ngoặc nhọn sao?"

"Bạn có thể. Nhưng những hạn chế này giống như privatecông cụ sửa đổi. Chúng tôi sử dụng công privatecụ sửa đổi để cố tình chặn quyền truy cập trực tiếp vào dữ liệu để các lập trình viên khác và lớp của họ sử dụng publiccác phương pháp của chúng tôi."

Điều tương tự cũng áp dụng cho một lớp trừu tượng. Bất cứ ai đã viết lớp không muốn bất cứ ai tạo ra các thể hiện của lớp. Ngược lại, tác giả mong muốn các phương thức trừu tượng của lớp trừu tượng của mình được kế thừa và ghi đè.

"Tôi vẫn không hiểu tại sao chúng ta lại muốn làm phức tạp cuộc sống của mình theo cách này."

"Ưu điểm của tính năng này là rõ ràng trong các dự án lớn. Bạn càng có nhiều lớp, bạn càng cần phân định rõ ràng vai trò của chúng. Bạn sẽ thấy lợi thế của việc này và sẽ sớm thôi. Mọi người đều phải trải qua điều này."