Quyền truy cập
Một cú pháp đặc biệt được cung cấp để chỉnh sửa quyền truy cập vào các thành viên của lớp (chúng ta đã gặp nó trong chương về cấu trúc). Tại bất kỳ đâu trong khối, trước khi mô tả các thành viên của lớp, bạn có thể chèn một bộ điều chỉnh: một trong ba từ khóa – private
, protected
, public
– và một dấu hai chấm.
Tất cả các thành viên theo sau bộ điều chỉnh, cho đến khi gặp một bộ điều chỉnh khác hoặc đến cuối lớp, sẽ nhận được giới hạn hiển thị tương ứng.
Ví dụ, đoạn mã sau tương đương với mô tả trước đó của lớp Shape
, bởi vì chế độ private
được giả định cho các lớp không có bộ điều chỉnh:
class Shape
{
private:
int x, y; // tọa độ tâm
color backgroundColor; // màu nền
...
};
2
3
4
5
6
7
Nếu chúng ta muốn mở quyền truy cập vào tất cả các trường, chúng ta sẽ thay đổi bộ điều chỉnh thành public
class Shape
{
public:
int x, y; // tọa độ tâm
...
};
2
3
4
5
6
Nhưng điều đó sẽ vi phạm nguyên tắc đóng gói, và chúng ta sẽ không làm vậy. Thay vào đó, chúng ta chèn bộ điều chỉnh protected
: nó cho phép truy cập vào các thành viên từ các lớp dẫn xuất trong khi vẫn giữ chúng ẩn khỏi thế giới bên ngoài. Chúng ta đang lên kế hoạch mở rộng lớp Shape
thành nhiều lớp hình dạng khác sẽ cần truy cập vào các biến của lớp cha.
class Shape
{
protected:
int x, y; // tọa độ tâm
color backgroundColor; // màu nền
public:
string toString() const
{
return (string)x + " " + (string)y;
}
void draw() { /* phần giữ chỗ giao diện vẽ hình dạng */ }
};
2
3
4
5
6
7
8
9
10
11
12
13
14
Dọc theo quá trình, chúng ta đã làm cho cả hai hàm trở thành public
.
Các bộ điều chỉnh có thể được xen kẽ trong mô tả lớp theo cách tùy ý và lặp lại nhiều lần. Tuy nhiên, để cải thiện tính đọc hiểu của mã, nên tạo một phần cho các thành viên public
, protected
, và private
, đồng thời duy trì thứ tự này trong tất cả các lớp của dự án.
Lưu ý rằng chúng ta đã thêm từ khóa const
vào cuối tiêu đề của hàm toString
. Điều này có nghĩa là hàm không thay đổi trạng thái của các trường của đối tượng. Mặc dù không bắt buộc, nó giúp ngăn chặn việc vô tình làm hỏng các biến và cũng cho người dùng lớp và trình biên dịch biết rằng việc gọi hàm sẽ không gây ra bất kỳ tác dụng phụ nào.
Trong hàm toString
, cũng như trong bất kỳ phương thức nào của lớp, các trường có thể được truy cập bằng tên của chúng. Sau này, chúng ta sẽ thấy cách khai báo các phương thức tĩnh: chúng hoàn toàn liên quan đến lớp, không phải các thể hiện của đối tượng, và do đó các trường không thể được truy cập.
Bây giờ chúng ta có thể gọi phương thức toString
từ biến đối tượng s
:
void OnStart()
{
Shape s;
Print(s.toString());
}
2
3
4
5
Ở đây chúng ta thấy việc sử dụng ký tự chấm '.' như một toán tử giải tham chiếu đặc biệt: nó cung cấp quyền truy cập vào các thành viên của đối tượng — các trường và phương thức. Bên trái của nó phải là một đối tượng, và bên phải — định danh của một trong những thuộc tính khả dụng.
Phương thức toString
là public
, và do đó có thể truy cập từ hàm bên ngoài lớp OnStart
. Nếu chúng ta thử trong OnStart
để "với tới" các trường s.x
hoặc s.y
qua giải tham chiếu, chúng ta sẽ nhận được lỗi biên dịch "không thể truy cập thành viên được bảo vệ được khai báo trong lớp 'Shape'".
Đối với các chuyên gia C++, chúng ta lưu ý rằng MQL5 không hỗ trợ cái gọi là "bạn bè" (đối với những người còn lại, hãy giải thích rằng trong C++ có thể, nếu cần, tạo một dạng "danh sách trắng" của các lớp và phương thức bên thứ ba có quyền mở rộng, mặc dù chúng không phải là "họ hàng").
Khi chúng ta chạy chương trình, chúng ta sẽ thấy rằng nó xuất ra một cặp số. Tuy nhiên, các giá trị tọa độ sẽ là ngẫu nhiên. Ngay cả khi bạn may mắn thấy các số không, điều đó không đảm bảo rằng chúng sẽ xuất hiện lần tiếp theo bạn chạy tập lệnh. Theo quy tắc, nếu danh sách các chương trình MQL đang thực thi không thay đổi trong terminal, việc chạy lại bất kỳ tập lệnh nào dẫn đến việc cấp phát cùng một vùng bộ nhớ cho nó, điều này có thể tạo ấn tượng sai lầm rằng trạng thái của đối tượng là ổn định. Trên thực tế, các trường của một đối tượng, cũng như trong trường hợp của các biến cục bộ, không được khởi tạo với bất kỳ giá trị nào theo mặc định (xem phần Khởi tạo).
Để khởi tạo chúng, các hàm đặc biệt của lớp, gọi là hàm tạo, được sử dụng.