1. Lớp cơ sở chung

Hôm nay chúng ta sẽ thưởng thức một loạt các chủ đề thú vị. Bạn có nhớ khi chúng tôi giới thiệu ChessItemlớp cơ sở để đơn giản hóa tất cả các lớp đại diện cho các quân cờ không? Tôi hy vọng như vậy 🙂

Bây giờ hãy tưởng tượng rằng mỗi phần có một draw()phương thức xử lý việc vẽ nó trên màn hình. Bạn gọi draw()phương thức và mảnh sẽ tự vẽ ở tọa độ hiện tại của nó. Sẽ thuận tiện hơn nếu chuyển phương thức này sang lớp cơ sở.

Nếu draw()phương thức nằm trong lớp cơ sở ChessItem, thì chúng ta có thể ghi đè lên nó trong các lớp mảnh và viết mã thanh lịch như sau:

class ChessBoard
{
   public void drawAllChessItems()
   {
      // Add the pieces to the list
      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();
      }
   }
}

Bằng cách giới thiệu ChessItemlớp cơ sở, chúng tôi có thể đơn giản hóa rất nhiều mã: không cần gọi các phương thức của từng lớp riêng biệt, chúng tôi có thể dễ dàng lưu trữ tất cả các đối tượng trong một bộ sưu tập duy nhất, v.v.

draw()Nhưng đây là một câu hỏi thú vị: phương thức được khai báo trực tiếp trong lớp nên vẽ gì ChessItemtrên màn hình? Rốt cuộc, không có quân cờ nào như vậy trong cờ vua, vì vậy không có gì để vẽ.

Điều đó hoàn toàn chính xác. Hơn nữa, thật vô nghĩa khi tạo ChessItemcác đối tượng trực tiếp. Nó không phải là một quân cờ, mà chỉ là một sự trừu tượng hóa — một lớp mà chúng tôi đã tạo ra để thuận tiện cho chúng tôi. Đây là cách trừu tượng hóa hoạt động trong OOP : chúng tôi di chuyển dữ liệu và phương thức quan trọng (được chia sẻ bởi tất cả các phần) sang một lớp cơ sở và giữ sự khác biệt của chúng trong các lớp hậu duệ riêng biệt.


2. Các lớp trừu tượng

lớp trừu tượng

Đối với những tình huống như vậy, Java có một loại lớp đặc biệt: lớp trừu tượng . Chúng được thiết kế để giúp các lập trình viên làm việc với các lớp tương tự dễ dàng hơn và giảm số lượng mã trùng lặp trong đó.

Dưới đây là ba điều cần biết về các lớp trừu tượng.

Phương pháp không có thực hiện

Một lớp trừu tượng có thể có khai báo phương thức mà không cần triển khai. Đây chính xác là những gì làm cho phương pháp trở nên trừu tượng. Phần thân của phương thức được thay thế đơn giản bằng dấu chấm phẩy. Và trước tên của phương thức, chúng tôi viết abstracttừ khóa. Ví dụ:

public abstract class ChessItem
{
   public int x, y; // Coordinates
   private int value; // The piece's value
   public int getValue() // Ordinary method that returns value field
   {
      return value;
   }

   public abstract void draw(); // Abstract method. The implementation is missing.
}

lớp trừu tượng

Mỗi phương thức không có triển khai đượ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 từ abstractkhóa.

Cấm tạo đối tượng

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

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

Kế thừa một lớp trừu tượng

Nếu lớp của bạn kế thừa một lớp trừu tượng, thì 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 cần viết một triển khai cho chúng. Nếu không, bản thân lớp của bạn cũng sẽ phải được khai báo là trừu tượng.

Nếu một lớp thậm chí có một phương thức chưa thực hiện được khai báo trực tiếp trong nó hoặc được kế thừa từ một lớp cha, thì lớp đó được coi là trừu tượng.

Và tại sao tất cả điều này là cần thiết? Tại sao các lớp trừu tượng cần thiết? Không thể sử dụng những cái bình thường thay thế? Và thay vì các phương thức trừu tượng, chúng ta không thể viết hai dấu ngoặc nhọn trống làm phần thân phương thức sao?

Chúng ta có thể. Nhưng những hạn chế này gần giống với privatecông cụ sửa đổi. Chúng tôi sử dụng từ khóa riêng tư để cố ý ngăn các lập trình viên khác truy cập trực tiếp vào dữ liệu và buộc họ chỉ sử dụng các phương thức công khai của chúng tôi khi viết các lớp của họ.

Nó giống với các lớp trừu tượng. Tác giả của một lớp trừu tượng không muốn các đối tượng của lớp được tạo ra. Thay vào đó, tác giả mong muốn các phương thức trừu tượng được kế thừa từ lớp trừu tượng và sau đó được ghi đè.

Ưu điểm của phương pháp này là dễ thấy trong các dự án lớn. Càng có nhiều lớp, bạn càng cần phân định rõ vai trò của chúng. Bạn sẽ thấy lợi ích của phương pháp này trong tương lai gần. Mọi thứ đều trải qua điều này.