C# - C Sharp: Đóng gói (Encapsulation)

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Tổng quan

Xét một tình huống trong đó bạn muốn học cách lái xe ôtô. Như một người học, bạn không cần phải hiểu xem ôtô làm việc thế nào, cấu tạo bình xăng thế nào, nguyên lý của việc rẽ phải rẽ trái ra làm sao, ... Như một người lái xe, bạn quan tâm đến việc khởi động và tắt xe cũng như cách cung cấp nhiên liệu cho xe. Ngoài ra, bạn có thể muốn tìm hiểu cách sử dụng cần số và hãm phanh để hiểu một cách đầy đủ về chiếc xe. Vì thế, để lái một ôtô, bạn chỉ cần quan tâm đến giao diện (interface) của nó, mà không cần biết về cách thức hoạt động của các thành phần hay bộ phận của xe.

Tương tự như vậy, trong lập trình hướng đối tượng, khái niệm che giấu đi những chi tiết của một đối tượng được thực hiện bằng cách sử dụng biện pháp Đóng gói (Encapsulation).

Đóng gói là một cơ chế liên kết mã lệnh và dữ liệu với nhau trong một lớp. Tất cả các chi tiết thực thi của một lớp không cần phải hiện diện so với các lớp khác cũng như các đối tượng mà sử dụng nó. Thay vào đó, chỉ những thông tin cần thiết thì mới hiện diện so với các thành phần khác của ứng dụng và phần còn lại có thể được ẩn đi. Điều này được thực hiện thông qua cơ chế đóng gói. Nói cách khác, có thể nói rằng trong các ngôn ngữ lập trình hướng đối tượng, đóng gói bao gồm các hoạt động bên trong của một đối tượng C#. Mục đích chính của việc che dấu trong một lớp là để giảm đi sự phức tạp trong phát triển phần mềm. Bằng cách che dấu những chi tiết thực thi về những gì được yêu cầu để thực hiện những hoạt động cần thiết trong lớp, việc sử dụng các hoạt động trở nên đơn giản hơn. Trong C#, việc che dấu được thực hiện bởi các bổ từ truy cập.

Đóng gói dữ liệu che dấu những biến thể hiện mà thể hiện trạng thái của đối tượng. Vì vậy, việc tương tác hay thay đổi dữ liệu đối với các loại biến thể hiện này được thực hiện thông qua các property. Ví dụ, để thay đổi tên (name) của chủ tài khoản hoặc muốn xem thông tin về tên của chủ tài khoản, ta có thể xây dựng một property có tên chẳng hạn như Name, trong Name sẽ xây dựng các bộ truy cập setter và getter.

Các bổ từ truy cập

Bổ từ truy cập xác định cách mà các thành phần của một lớp có thể được truy cập từ bên ngoài lớp đó. Nói cách khác, bổ từ truy cập định nghĩa tầm vực hay mức độ che dấu của các thành phần. Các bổ từ truy cập thường được đặt ở vị trí đầu tiên trong khi khai báo các thành phần của lớp. Phạm vi hay tầm vực của các thành phần cũng có liên hệ mật thiết với các namespace.

C# cung cấp bốn loại bổ từ truy cập cơ bản như sau:

- public: Cung cấp cấp độ truy cập rộng nhất. Các thành phần khai báo là public có thể được truy cập từ bất kỳ đâu trong lớp cũng như từ tất cả các lớp khác.

- private: Cung cấp cấp độ truy cập hẹp nhất. Các thành phần private chỉ có khả năng được truy cập từ bên trong lớp mà chúng được khai báo.

- protected: Bổ từ truy cập này cho phép các thành phần lớp có thể được truy cập từ bên trong lớp chứa chúng cũng như từ các lớp thừa kế.

- internal: Bổ từ truy cập này chỉ cho phép các thành phần của một lớp có thể truy cập trong cùng assemply.

Chi tiết về các mức truy cập xin xem tại bài viết Các mức khả năng truy cập.

Như là một quy tắc chung trong C#, những chi tiết cũng như sự thực thi của một lớp được che dấu đi từ các lớp khác hoặc những đối tượng mở rộng trong ứng dụng. Điều này được thực hiện bằng cách đặt các biến thể hiện có mức truy cập là private và các phương thức thể hiện có mức truy cập là public.

Đoạn mã 1 dưới đây cho thấy việc sử dụng khái niệm đóng gói trong lớp ChuNhat.

Đoạn mã 1:

namespace ConsoleApp1
{
 public class Rectangle
 {
  //khai báo các biến thể hiện
  private int width;
  private int height;

  /* định nghĩa hàm tạo không tham số */
  public Rectangle()
  {
   Console.WriteLine("Hàm tạo được gọi ...");
   width = 10;
   height = 10;
  }

  /* định nghĩa hàm tạo hai tham số */
  public Rectangle(int width, int height)
  {
   Console.WriteLine("Hàm tạo hai đối số được gọi ...");
   this.width = width;
   this.height = height;
  }

  /* hiển thị các chiều của đối tượng hình chữ nhật */
  public void HienThiCacChieu()
  {
   Console.WriteLine($"Width: {width}");
   Console.WriteLine($"Height: {height}");
  }
 }
}

Đoạn mã 1 ở trên sử dụng bổ từ truy cập của các biến thể hiện là width và height của lớp Rectangle là private. Điều này có nghĩa là không thể trực tiếp truy cập các trường này từ bên ngoài lớp. Mục đích của việc này là để hạn chế việc truy cập đến các thành phần dữ liệu của lớp. Tương tự, bổ từ truy cập cho các phương thức được sử dụng là public. Do đó, người dùng có thể truy cập các thành phần lớp thông qua các phương thức của nó mà không ảnh hưởng đến việc thực thi bên trong của lớp.

Property với các bộ truy cập setter và getter

Ở đoạn mã 1 bên trên, vì các biến thể hiện width và height được đóng gói là private, nên ta không thể truy cập đến chúng từ bên ngoài lớp Rectangle. Tuy nhiên, có một số tình huống mà ta cần phải lấy hoặc thay đổi giá trị cho những biến thể hiện này, ví dụ như sử dụng một phương thức từ một lớp khác để nhập liệu cho chúng. Để giải quyết vấn đề này, ta xây dựng các property trong đó có các bộ truy cập settergetter.

Bộ truy cập setter và getter

setter và getter có cú pháp xây dựng cơ bản như sau:

bổ_từ_truy_cập kiểu_dữ_liệu Tên_property {
  get => tên_biến_thể_hiện;
  set => tên_biến_thể_hiện = value;
}

Đoạn mã 2 dưới đây định nghĩa các property cho hai trường width và height của lớp Rectangle.

Đoạn mã 2:

public void setRong(int rong) {
  this.rong = rong;
}
public void setCao(int cao) {
  this.cao = cao;
}

Phương thức getter

getter dùng để lấy giá trị của biến thể hiện. Cú pháp cho phương thức getter là như sau:

bổ_từ_truy_cập kiểu_trả_về tên_getter() {
  return tên_biến_thể_hiện;
}

trong đó,

bổ_từ_truy_cập: không được là private.

kiểu_trả_về: giống với kiểu của tên_biến_thể_hiện.

Đoạn mã 3 định nghĩa các phương thức getter cho hai biến thể hiện rong và cao.

Đoạn mã 3:

public void getRong() {
  return rong;
}
public void getCao() {
  return cao;
}

Xem thêm:

» Tiếp: Class
« Trước: record
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!