Trang chủ C# hướng đối tượng Các loại phạm vi truy cập trong C#

Các loại phạm vi truy cập trong C#

Nguyễn Dương 07-06-2024

Trong các bài viết trước, các bạn có thấy ở một số biến, một số class mình đều có từ khóa như public ở đầu. Việc chèn từ khóa này để quy định phạm vi truy cập cho thành phần đó. Trong bài viết này chúng ta cùng tìm hiểu về các loại phạm vi hoạt động trong C# nhé.

1. CÁC LOẠI PHẠM VI TRUY CẬP

Trong C# có 5 loại phạm vi truy cập:
Phạm vi truy cập
Ý nghĩa

public
Thành phần mang thuộc tính này có thể được truy cập ở bất kỳ vị trí nào.
Không hạn chế khả năng truy cập.
private
Nghĩa là thành phần riêng, chỉ nội bộ bên trong lớp chứa nó mới có quyền truy cập.
protected
Tương tự như private, ngoài ra thì có thể truy cập từ lớp dẫn xuất lớp chứa nó. (Tính kế thừa)
internal
Chỉ được truy cập trong cùng một Assembly (cùng project). Thuộc tính này thường được dùng cho class.
protected internal
Tương tự như internal, ngoài ra thì có thể truy cập từ lớp dẫn xuất lớp chứa nó. (Tính kế thừa)

Lưu ý:
- Nếu khai báo lớp mà không chỉ ra phạm vi cụ thể thì phạm vi mặc định là internal.
- Nếu khai báo thành phần bên trong lớp mà không chỉ ra phạm vi cụ thể thì phạm vị mặc định là private.
Quy định phạm vi truy cập là thể hiện tính đóng gói trong lập trình hướng đối tượng. Tùy từng thành phần mà chúng ta quy định phạm vi truy cập cho chúng. Có những thành phần mà có thể cho mọi người đều truy cập được, có những thành phần sẽ phải hạn chế người truy cập. Thậm chí còn phải che giấu đi thông tin, chi tiết cài đặt.

Một ví dụ về tính đóng gói:
Apple sản xuất ra chiếc điện thoại IPhone nhưng người sử dụng chỉ có thể động chạm tới màn hình, vỏ ngoài, khe sạc, khe cắm tai nghe, nút Home, nút nguồn. Còn các mạch điện tử bên trong thì không nhìn thấy, không chạm tới được. 

- Các thuộc tính thường sẽ có phạm vi truy cập là private. Vì đây chính là các thông tin nội bộ của lớp không thể để truy cập 1 cách tuỳ tiện được.
- Các phương thức thường sẽ có phạm vi truy cập là public. Vì đây là các thao tác mà lớp hỗ trợ cho chúng ta thực hiện những công việc nhất định nên cần phải cho phép mọi người đều có thể sử dụng được.

Ví dụ: Tạo một lớp People nhưng các biến đều để phạm vi là private
class People
{
        private string Name;
        private int ID;
        private int Age;

        public void ShowInfo()
        {
            Console.WriteLine("Ho ten: {0}, ID: {1}, tuoi: {2}", Name, ID, Age);
        }

}

Trong hàm Main, mình tạo một P1 (kiểu People) nhưng khi thao tác với P1 thì không thể truy cập vào các biến Name, ID, Age được. Chỉ thao tác được với hàm ShowInfo.


2. HÀM TRUY VẤN, HÀM CẬP NHẬT

Nếu thuộc tính trong một lớp là private mà người dùng vẫn muốn xem thông tin hoặc thay đổi giá trị thì phải dùng đến hàm truy vấn và hàm cập nhật.

Hàm truy vấn giúp người dùng có thể xem được dữ liệu của một thuộc tính nào đó, trả về giá trị của thuộc tính tương ứng.

Hàm cập nhật giúp người dùng có thể thay đổi giá trị của một thuộc tính nào đó. 

Hàm truy vấn hay hàm cập nhật chỉ là một hàm bình thường. Cách khai báo và sử dụng hoàn toàn như các hàm khác.

Lưu ý khi sử dụng hàm truy vấn và hàm cập nhật
- Những hàm truy vấn nên bắt đầu bằng từ khoá get và kèm theo sau là tên thuộc tính tương ứng. Ví dụ như getName(), getDiemToan
- Những hàm cập nhật nên bắt đầu bằng từ khoá set và kèm theo sau là tên thuộc tính tương ứng. Ví dụ như setName(), setDiemVan()
- Nếu thuộc tính kiểu luận lý (bool) thì tên hàm truy vấn nên bắt đầu bằng từ khoá is và kèm theo sau là tên thuộc tính tương ứng.
- Hàm truy vấn sẽ có kiểu trả về trùng với kiểu dữ liệu của thuộc tính tương ứng và không có tham số truyền vào.
- Hàm cập nhật sẽ có kiểu trả về là void và có 1 tham số truyền vào có kiểu dữ liệu trùng với kiểu dữ liệu của thuộc tính tương ứng.

Ví dụ: hàm getName
public string getName()
{
      return Name;
}


Ví dụ: Thay đổi giá trị biến Name có phạm vi là private.
namespace ConsoleApp10
{
    class People
    {
        private string Name;
        private int ID;
        private int Age;

        public People(string name, int id, int age)
        {
            Name = name;
            ID = id;
            Age = age;
        }

        public void setName(string name)
        {
            Name = name;
        }

        public void ShowInfo()
        {
            Console.WriteLine("Ho ten: {0}, ID: {1}, tuoi: {2}", Name, ID, Age);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            People P1 = new People("Nguyen Duong", 123456, 26);
            P1.ShowInfo();

            P1.setName("Vu Thi Thuy");
            P1.ShowInfo();

            Console.ReadLine();
        }
    }
}

Kết quả:

Bạn có thể thấy rõ ràng là biến Name mình đặt phạm vi truy cập là private nhưng mình vẫn có thể thay đổi giá trị với hàm setName. Sau khi chạy hàm setName thì chương trình đã đổi tên Nguyen Duong thành Vu Thi Thuy.


3. PROPERTY TRONG C#

 Trong C#, hàm truy vấn và hàm cập nhật đã được nâng cấp lên thành 1 cấu trúc mới ngắn gọn hơn và tiện dụng hơn đó là property. Sử dụng property giúp chúng ta có thể thao tác dễ dàng hơn nhưng vẫn đảm bảo tính đóng gói của lập trình hướng đối tượng.

Cú pháp:
<kiểu dữ liệu> <tên property>
{
       get { return <tên thuộc tính>; }
       set { <tên thuộc tính> = value; }
}

<kiểu dữ liệu> là kiểu dữ liệu của property. Thường sẽ trùng với kiểu dữ liệu của thuộc tính private tương ứng bên trong lớp.
<tên property> là tên do bạn tự đặt và tuân theo quy tắc đặt tên biến.
- Dòng get tương đương với hàm truy vấn.
- Dòng set tương đương với hàm cập nhật.
- Từ khoá value đại diện cho giá trị mà người gán vào property 
<tên thuộc tính> là tên thuộc tính thực sự bên trong lớp.

Nói cách khác thay vì bạn sử dụng riêng lẻ hàm truy vấn và hàm cập nhật thì bạn gom chúng vào một phương thức. Code ngắn gọn hơn, sử dụng tiện hơn.

Ví dụ: gom hàm getAge và setAge vào trong 1 property

Trong class People
public int age
{
      get { return Age; }
      set { Age = value; }
}

Trong hàm Main
People P1 = new People("Nguyen Duong", 123456, 28);
P1.ShowInfo();

P1.age = 23;
P1.ShowInfo();

Console.ReadLine();

Kết quả:


Mình đã gom get và set vào trong 1 property và sử dụng, kết quả là phần tuổi 28 đã được đổi thành 23.

Lưu ý:
- Tên property thường phải làm gợi nhớ đến tên thuộc tính private bên trong lớp.
- Tuỳ theo nhu cầu và tính bảo mật mà lập trình viên có thể ngăn không cho gán giá trị hoặc ngăn không cho lấy dữ liệu bằng cách bỏ đi từ khoá tương ứng.

Bài viết liên quan

Interface trong C# Interface trong C#
Tính đa hình trong C# Tính đa hình trong C#
Tính kế thừa trong C# Tính kế thừa trong C#
this và static trong C# this và static trong C#
Các loại phạm vi truy cập trong C# Các loại phạm vi truy cập trong C#
Hàm khởi tạo và hàm hủy Hàm khởi tạo và hàm hủy