2009-04-03 51 views
13

Lợi ích của việc xác định thuộc tính riêng thay vì thuộc tính công khai là gì? Tại sao tôi nên có thêm công việc tạo phương pháp để truy cập và sửa đổi các thuộc tính riêng tư nếu tôi có thể chỉ công khai chúng?Tuyên bố thuộc tính lớp: riêng tư và công khai

Trả lời

9

Nếu bạn sử dụng getters/setters, bạn có thể thực hiện logic khi thay đổi hoặc truy cập. Bạn có thể xác thực đầu vào, thay vì giả sử nó luôn đúng. Bạn có thể theo dõi số lần tìm nạp giá trị bao nhiêu lần.

Hầu hết tất cả, đó là thiết kế tốt. Nó cung cấp cho bạn, nhà phát triển của lớp, kiểm soát nhiều hơn cách nó được sử dụng và khả năng ngăn chặn lạm dụng, lạm dụng hoặc chỉ một người nào đó làm điều gì đó sai trái.

0

Nếu bạn tạo phương thức truy cập, bạn tách riêng triển khai khỏi giao diện.

+0

... và tại sao điều đó lại mong muốn? – Rob

+0

@Rob Sau đó, việc triển khai có thể thay đổi hoàn toàn và bất kỳ mã nào sử dụng giao diện không bao giờ phải biết về nó. – Kalium

2

Bởi vì bạn nên luôn cố gắng bảo vệ việc triển khai từ giao diện. Nếu bạn đặt thuộc tính là công khai, bạn sẽ cho khách hàng biết cách triển khai của bạn cho thuộc tính đó.

Điều này liên kết bạn không chỉ giữ giao diện mà còn thực hiện.

Ngoài ra, bạn có thể thực hiện những việc thông minh khác như xác thực, kiểm soát truy cập, kế toán, nếu bạn sử dụng một phương pháp. Nếu bạn đặt thuộc tính là công khai, bạn có ít quyền kiểm soát hơn đối với những gì khách hàng có thể thực hiện với thuộc tính đó

0

Thuộc tính riêng cung cấp cho bạn mức độ bảo vệ từ người dùng thuộc lớp của bạn, cho thuộc tính đó. Nếu bạn sử dụng thuộc tính công khai, bạn sẽ cần thêm nhiều logic hơn để kiểm tra các giá trị không hợp lệ ở phía trước, có thể hoạt động hiệu quả hơn, cũng như tốn kém tính toán hơn.

Thuộc tính công khai cũng "lộn xộn" giao diện. Bạn càng có ít thuộc tính công khai hơn, đối tượng "sạch hơn" và dễ dàng hơn đối tượng của bạn sẽ làm việc. Có một số thuộc tính riêng tư mang lại cho bạn sự linh hoạt trong khi cung cấp sự dễ sử dụng mà nếu không sẽ không có ở đó.

0

Trong C# nó là thành ngữ. Điều đó có nghĩa là các lĩnh vực công cộng sẽ gây ngạc nhiên và làm cho người khác mất nhiều thời gian hơn để hiểu mã của bạn.

Lý do là thành ngữ phải làm với các giải thích khác mà mọi người đang đưa ra, nhưng thực tế là thành ngữ có nghĩa là bạn nên chọn thuộc tính trên trường công cộng trừ khi có lý do thuyết phục để sử dụng trường.

11

Trong ngắn hạn không có gì, ngoài việc làm OOP thuần túy không hài lòng.

(Tôi giả sử bạn có nghĩa là trưng bày các thuộc tính mà nếu không sẽ sử dụng getters/setters - rõ ràng là có sự khác biệt lớn nếu bạn để TẤT CẢ các thuộc tính của bạn công khai).

Về lâu dài, có một vài lý do thực sự tốt để thực hiện.

Thứ nhất nó cho phép bạn xác thực đầu vào tại nguồn của nó thay vì sau đó phải theo dõi lại nguồn gốc bằng kết hợp điểm ngắt phần cứng và ma thuật đen.

Ví dụ:

void Foo::setWeight(float weight) 
{ 
    ASSERTMSG(weight >= 0.0f && weight <= 1.0f, "Weights must fall in [0..1]"); 
    mWeight = weight; 
} 

Nó cũng cho phép bạn thay đổi hành vi của đối tượng mà không cần phải cấu trúc lại mã máy khách.

Ví dụ:

void Foo::setSomething(float thing) 
{ 
    mThing = thing; 
    // 2009/4/2: turns out we need to recalc a few things when this changes.. 
    ... 
} 
1

Chủ yếu là do khái niệm đóng gói OO. Sử dụng cá nhân bạn đóng gói truy cập vào biến đối tượng của bạn giữ sự kiểm soát của trạng thái đối tượng. Không cho phép các đối tượng bên ngoài thay đổi trạng thái của đối tượng mà bạn không biết.

Ví dụ đơn giản sẽ là đối tượng Bỏ túi.

class Pocket { 
public int numberOfCoins = 10; 
private boolean haveMoney = true; 

public void giveOneCoin(){ 
    if(stillHaveMoney()){ 
    numberOfCoins--; 
    if(numberOfCoins=<0){ 
     haveMoney=false; 
    } 
    } 
} 

public boolean stillHaveMoney(){ 
    return haveMoney; 
} 

} 

Và bây giờ tưởng tượng một lớp học như sau:

class PickPockets { 
    public void getSomeMoney(Pocket pocket){ 
     pocket.numberOfCoins=0; 
    } 
} 

Chắc chắn đó là một ví dụ đơn giản. tuy nhiên điều này cho thấy việc kiểm soát truy cập vào các trường/thuộc tính lớp của bạn quan trọng như thế nào. Hãy tưởng tượng một đối tượng phức tạp hơn với điều khiển trạng thái phức tạp hơn nhiều. Đóng gói làm cho sự trừu tượng và nhất quán của đối tượng tốt hơn.

+0

Chà, nhưng khi nào là lần cuối cùng một lớp học của bạn bị lừa đảo và bắt đầu ăn cắp tiền từ các đồ vật khác? – fauxCoder

+0

Trong tương lai khi mã lớn hơn và ai đó muốn sử dụng mã, Ai đó có thể thấy thuộc tính numberOfCoins là công khai và chỉ cần thay đổi trực tiếp để nhận kết quả. Nhưng sau đó khi họ gọi hàm hasMoney mong đợi nó chính xác, họ có thể nhận được một kết quả không chính xác. – kiwicomb123

0

Thông thường bạn sẽ sử dụng các khai báo riêng cho các trường bạn muốn tách biệt trong logic của chương trình, CHỈ nếu bạn thấy cần thiết.

Tuyên bố công khai cho phép bạn kiểm soát nhiều hơn luồng của chương trình của riêng bạn; bạn có thể thay đổi các trường công khai bất cứ khi nào bạn muốn. Bạn là người đàn ông trong nhà.

Vì vậy, tại sao hầu hết mọi người phản ứng một cách tự nhiên với một tờ khai CÓ LỚN với Riêng tư?

Bởi vì:

  • Họ được dạy để làm điều đó "chỉ thích rằng" ở đại học. (lý do thận trọng nhất)
  • Cuối cùng, ngu xuẩn và ngay lập tức cho rằng bạn đang xây dựng thư viện mã, xây dựng thành phần phần mềm cho người khác để tiêu thụ HOẶC làm việc trên một số triển khai mã hóa. CHỈ trong những trường hợp này bạn sẽ không chắc chắn điều gì sẽ xảy ra với các lĩnh vực của mình.

Tóm lại là đáng kinh ngạc "thương mại" !! Nếu bạn đang "bán" nó, sau đó đi tư nhân, nếu không làm những gì bạn thích.

0

Bạn nên sử dụng lâu dài nếu tất cả thuộc tính là riêng tư. Điều đó bao gồm không sử dụng getters. Nếu bạn đang truy cập các thuộc tính của các đối tượng thì bạn đang phá vỡ đóng gói, và không thực sự làm OOP cả. Tại thời điểm đó, hầu hết lý do để xây dựng một lớp học đã bị lãng phí. Tại sao xây dựng một lâu đài để bảo vệ khỏi những kẻ xâm nhập, sau đó để lại tất cả các cửa mở? Hoặc (với getters) luôn chào đón những kẻ xâm nhập theo yêu cầu.

Các phương pháp của "Luật Demeter" và "Nói không hỏi" đã được chứng minh là giảm tỷ lệ lỗi trong mã sản xuất. Sử dụng các thuộc tính công khai sẽ không làm cho những người theo chủ nghĩa thuần túy hướng đối tượng không hài lòng, nó sẽ chỉ ngăn cản họ sử dụng mã của bạn.

Cho các đối tượng của bạn biết phải làm gì với các thuộc tính của chúng, không hỏi chúng về các giá trị, thao tác và ghi chúng lại. Điều đó giống như việc dắt chó đi dạo và sau đó nhặt từng chân một để nó di chuyển.

Nhân tiện, ngược lại, hành vi phải được công khai. Bất kỳ phương pháp nào có vẻ như nó phải là riêng tư thực sự là một phương pháp chưa được rút gọn của một lớp khác. Trích xuất lớp và phương thức đó và xem thiết kế của bạn đơn giản hóa trước mắt bạn.

Các vấn đề liên quan