chỉnh sửa: Đọc faq lâu hơn một chút Tôi thích ý tưởng về toán tử << >> nạp chồng và thêm làm bạn của các lớp đó, tuy nhiên tôi không chắc làm thế nào điều này không phá vỡ đóng gói
Làm thế nào nó sẽ phá vỡ đóng gói?
Bạn phá vỡ đóng gói khi bạn cho phép truy cập không hạn chế vào một thành viên dữ liệu. Hãy xem xét các lớp sau:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
được rõ ràng là không được đóng gói. Bất cứ ai cũng có thể đọc và sửa đổi x
trong đó. Chúng tôi không có cách nào để thực thi bất kỳ loại kiểm soát truy cập nào.
c2
rõ ràng là gói gọn. Không có quyền truy cập công cộng vào x
. Tất cả những gì bạn có thể làm là gọi foo
hàm, thực hiện một số thao tác có ý nghĩa trên lớp .
c3
? Là ít đóng gói? Nó có cho phép truy cập không hạn chế x
? Nó có cho phép các chức năng chưa biết truy cập không?
Không. Nó cho phép chính xác một chức năng để truy cập các thành viên riêng của lớp. Cũng giống như c2
đã làm. Và cũng giống như c2
, một hàm có quyền truy cập không phải là "một số hàm ngẫu nhiên, không xác định", mà là "hàm được liệt kê trong định nghĩa lớp". Giống như c2
, chúng ta có thể thấy, chỉ bằng cách nhìn vào các định nghĩa lớp, một danh sách đầy đủ về những người có quyền truy cập.
Vì vậy, làm thế nào chính xác là điều này ít đóng gói? Cùng một lượng mã có quyền truy cập vào các thành viên riêng của lớp. Và tất cả những người có quyền truy cập được liệt kê trong định nghĩa lớp.
friend
không phá vỡ đóng gói. Nó làm cho một số người lập trình Java cảm thấy không thoải mái, bởi vì khi họ nói "OOP", họ thực sự có nghĩa là "Java". Khi họ nói "Đóng gói", họ không có nghĩa là "các thành viên riêng phải được bảo vệ khỏi các truy cập tùy ý", mà là "một lớp Java trong đó các hàm duy nhất có thể truy cập các thành viên riêng, là các thành viên của lớp", mặc dù điều này hoàn toàn vô nghĩa đối với nhiều lý do .
Đầu tiên, như đã được chỉ ra, nó quá hạn chế. Không có lý do tại sao các phương pháp bạn bè không nên được phép làm như vậy.
Thứ hai, nó không đủ hạn chế . Hãy xem xét một lớp thứ tư:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
Điều này, theo tâm lý Java đã nói ở trên, được gói gọn một cách hoàn hảo.
Tuy nhiên, nó cho phép hoàn toàn bất cứ ai đọc và sửa đổi x . Làm thế nào mà thậm chí có ý nghĩa? (gợi ý: Không)
Điểm mấu chốt: Đóng gói là về khả năng kiểm soát các chức năng có thể truy cập các thành viên tư nhân. Nó không phải là chính xác nơi định nghĩa của các chức năng này được đặt.