2009-08-05 15 views
7

Một quan niệm sai lầm phổ biến về mức truy cập trong Java, C#, C++ và PHP là nó áp dụng cho các đối tượng chứ không phải là các lớp. Tức là, một đối tượng của lớp X không thể nhìn thấy các thành viên riêng của X khác. Trong thực tế, tất nhiên, mức truy cập là dựa trên lớp và một đối tượng X có thể dễ dàng tham khảo các thành viên riêng của người khác.Có ngôn ngữ nào với các cấp truy cập dựa trên đối tượng không?

Có tồn tại ngôn ngữ với các cấp truy cập dựa trên đối tượng không? Họ có thay vì, hoặc ngoài việc truy cập dựa trên lớp học không? Tác động của tính năng này đối với thiết kế chương trình là gì?

+0

Tôi lấy quyền tự do thêm PHP vào danh sách ngôn ngữ triển khai cấp độ truy cập dựa trên lớp học. –

Trả lời

6

Ruby có cấp truy cập dựa trên đối tượng. Dưới đây là một trích dẫn từ lập trình Ruby:

Sự khác biệt giữa "bảo vệ" và "private" khá tinh tế, và là khác nhau trong Ruby hơn trong hầu hết các ngôn ngữ OO chung. Nếu phương pháp được bảo vệ là , nó có thể được gọi bởi bất kỳ trường hợp nào của lớp xác định hoặc lớp học lớp con của nó. Nếu một phương pháp là tư nhân, nó có thể được gọi chỉ trong bối cảnh của đối tượng gọi điện thoại --- nó không bao giờ là thể truy cập phương pháp riêng của đối tượng khác trực tiếp, ngay cả khi đối tượng là của lớp giống như người gọi.

Và đây là nguồn: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

Ví dụ sự khác biệt giữa Java và Ruby

Java

public class Main { 
    public static void main(String[] args) { 
     Main.A a1 = new A(); 
     Main.A a2 = new A(); 

     System.out.println(a1.foo(a2)); 
    } 

    static class A 
    { 
     public String foo(A other_a) 
     { 
      return other_a.bar(); 
     } 

     private String bar() 
     { 
      return "bar is private"; 
     } 
    } 
} 

// Outputs 
// "bar is private" 

của Ruby

class A 
    def foo other_a 
    other_a.bar 
    end 

    private 
    def bar 
    "bar is private" 
    end 
end 

a1 = A.new 
a2 = A.new 

puts a1.foo(a2) 

# outputs something like 
# in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError) 
+0

Bạn có thể cung cấp trích dẫn không? –

+0

Tôi vẫn đang tìm kiếm. –

+0

"Riêng tư" theo nghĩa này có vẻ thực sự là mô-đun. Tôi hy vọng các ngôn ngữ khác nhận được chức năng tương tự. – Imagist

-1

Bạn có thể thực hiện điều này trong C# bằng cách có một số phương pháp có khả năng đi bộ ngăn xếp và kiểm tra đối tượng người gọi và ném ngoại lệ nếu nó không phải là lớp hiện tại. Tôi không biết tại sao bạn muốn, nhưng tôi nghĩ tôi sẽ ném nó ra khỏi đó.

+0

Làm rõ: điều này nên được thực hiện tại thời gian biên dịch. Nó là vô ích khi chạy. – EFraim

+0

Wtf đã làm điều này có được downvoted cho? Đó là một câu trả lời hợp lệ ... –

+0

Không, đó là một sự phản đối. Tăng chi phí thời gian chạy khủng khiếp và sử dụng phương pháp hoàn toàn không chính xác. – EFraim

0

Lý do chính tại sao không có ngôn ngữ nào hỗ trợ cho điều này ở cấp ngữ nghĩa là các nhu cầu khác nhau quá khác nhau để tìm mẫu số chung đủ lớn cho một tính năng như vậy. Dữ liệu ẩn là đủ xấu như nó được, và nó được chỉ tồi tệ hơn khi bạn cần kiểm soát hạt mịn hơn.

Chẳng hạn, bạn có thể đánh dấu dữ liệu nhất định là riêng tư cho bất kỳ ai nhưng đối tượng đã tạo dữ liệu đó (mật khẩu sẽ là một ví dụ tuyệt vời: Ngay cả mã chạy trong cùng ứng dụng cũng không thể đọc được)).

Thật không may, điều này "bảo vệ" sẽ được bề ngoài kể từ khi ở cấp độ lắp ráp, bảo vệ sẽ không tồn tại. Để có hiệu quả, phần cứng sẽ cần hỗ trợ nó. Trong trường hợp này, có lẽ ở mức một byte đơn trong RAM. Điều đó sẽ làm cho một ứng dụng như vậy cực kỳ an toàn và chậm chạp.

Trong thế giới thực, bạn sẽ tìm thấy điều này trong TPM chip trên bo mạch chủ của bạn và, ở dạng rất thô, với các bảng MMU của CPU. Nhưng đó là ở cấp độ trang 4K, không phải ở cấp độ byte. Có các thư viện để xử lý cả hai nhưng không được tính là IMO "hỗ trợ ngôn ngữ".

Java có dạng như thế này dưới dạng Security API. Bạn phải quấn mã trong câu hỏi trong một người giám hộ yêu cầu SecuityManager hiện tại cho dù truy cập được phép hay không.

Trong Python, bạn có thể đạt được điều gì đó tương tự với trang trí (đối với phương pháp và chức năng) hoặc bằng cách thực hiện __setattr____getattr__ để truy cập trường.

+3

Phân tích của bạn là hợp lệ theo nghĩa nào đó, nhưng dường như bạn đang nhầm lẫn "đóng gói dữ liệu" với "bảo mật dữ liệu". Các công cụ sửa đổi công cộng, được bảo vệ và riêng tư trong các ngôn ngữ OOP không có nghĩa là "bảo mật" dữ liệu, mà là đóng gói dữ liệu trong một lớp và "bảo vệ" nó khỏi bị thay đổi bởi các lớp khác. Các công cụ sửa đổi không có nghĩa là "bảo vệ" dữ liệu theo nghĩa bảo mật thông tin. – mipadi

+0

Điều gì sẽ là điểm của một tính năng như vậy nếu không bảo mật? Để đóng gói dữ liệu, "riêng tư" là đủ bởi vì bạn luôn có thể quấn một trường duy nhất trong một lớp để bảo vệ quyền truy cập vào nó từ các trường hợp khác của cùng một lớp. –