2014-12-25 14 views
5

Tôi không hoàn toàn nhận được một số điều về mô hình đối tượng Ruby. Đầu tiên, là tất cả mọi thứ trong Ruby một ví dụ của Class? Những tất cả sản xuất đúng:Tại sao tất cả mọi thứ trong Class là Ruby?

p Object.instance_of?(Class) 
p Class.instance_of?(Class) 
p Module.instance_of?(Class) 
p BasicObject.instance_of?(Class) 
class Hello; end 
p Hello.instance_of?(Class) 

tôi không thể hoàn toàn nhận được thế nào là nó có thể, nếu Object là một lớp cha của Class, làm thế nào nó có thể là cả một lớp cha của Class và một thể hiện của nó cùng một lúc (hầu hết các sơ đồ trên mô hình đối tượng Ruby nêu rõ hệ thống phân cấp này)? Cho phép đối với một số crazyness như thế này:

p BasicObject.is_a?(Object) #=> true 

nơi BasicObject.classClass, và Class.is_a?(Object).

Nhân tiện, sử dụng Ruby 2.0.

Trả lời

11

Đầu tiên, là mọi thứ trong Ruby một thể hiện của Class?

Không, không phải mọi thứ đều là một phiên bản Class. Chỉ các lớp là các trường hợp của Class.

Có rất nhiều thứ không phải là trường hợp của Class: chuỗi, ví dụ: là các trường hợp String, không phải Class. Mảng là trường hợp của Array, nguyên là trường hợp của Integer, phao nổi là trường hợp của Float, true là một thể hiện của TrueClass, false là một thể hiện của FalseClass, nil là một thể hiện của NilClass, và vân vân.

Mỗi lớp là một thể hiện của Class, giống như mọi chuỗi là một thể hiện của String.

nếu Object là một lớp cha của Class, làm thế nào nó có thể là cả một lớp cha của Class và một thể hiện của nó cùng một lúc (hầu hết các sơ đồ trên Ruby Object Model nêu rõ hệ thống phân cấp này)?

Magic.

Giống như trong hầu hết các ngôn ngữ khác, có một số thực thể cốt lõi được cho là tồn tại đơn giản. Chúng rơi xuống từ bầu trời, hiện ra từ không khí mỏng, xuất hiện kỳ ​​diệu.

Trong Ruby, một số trong những điều kỳ diệu là:

  • Object không có một lớp cha, nhưng bạn không thể định nghĩa một lớp không có lớp cha, lớp cha trực tiếp ngầm luôn là Object. [Lưu ý: có thể có các lớp siêu thực hiện được xác định là Object, nhưng cuối cùng, sẽ có một lớp không có siêu lớp.]
  • Object là một thể hiện của Class, mà là một lớp con của Object (có nghĩa là gián tiếp Object là một thể hiện của Object chính nó)
  • Class là một lớp con của Module, đó là một thể hiện của Class
  • Class là một ví dụ của Class

Không có điều nào trong số này có thể được giải thích trong Ruby.

BasicObject, Object, ModuleClass tất cả cần phải đồng thời tồn tại cùng lúc vì chúng có phụ thuộc vòng tròn.

Chỉ vì mối quan hệ này không thể được thể hiện trong mã Ruby, không có nghĩa là đặc tả ngôn ngữ Ruby không thể nói nó phải như vậy. Nó tùy thuộc vào người triển khai để tìm ra cách để làm điều này. Sau khi tất cả, việc thực hiện Ruby có một mức độ truy cập vào các đối tượng mà bạn là một lập trình viên không có.

Ví dụ, triển khai Ruby trước tiên có thể tạo BasicObject, đặt cả con trỏ superclass và con trỏ class của nó thành null.

Sau đó, nó tạo ra Object, thiết lập con trỏ superclass của nó để BasicObjectclass con trỏ của nó để null.

Tiếp theo, nó tạo ra Module, đặt con trỏ superclass của mình thành Object và con trỏ class trỏ đến null.

Cuối cùng, nó tạo ra Class, thiết lập con trỏ superclass của nó để Moduleclass con trỏ của nó để null.

Bây giờ, chúng ta có thể ghi đè lên BasicObject 's, Object' s, Module 's, và Class' s class con trỏ để trỏ đến Class, và chúng tôi đang thực hiện.

Điều này rất dễ làm từ bên ngoài hệ thống, nó trông có vẻ lạ từ bên trong.

2

Bạn nên chú ý rằng:

p BasicObject.instance_of?(BasicObject) 

in false.

Đó là, khái niệm BasicObject không phải là một thể hiện của BasicObject, nó là một thể hiện của cái gì khác, có nghĩa là, nó là một đối tượng Class, đại diện cho một đối tượng chứa (ví dụ) các phương thức lớp, chẳng hạn như new.

Ví dụ:

p (BasicObject.new()).instance_of?(BasicObject) 

in true, và

p (BasicObject.new()).instance_of?(Class) 

in false.

0

Tất cả các ví dụ của bạn đều theo các lớp định nghĩa. Các lớp cũng là các đối tượng. Nhưng những gì bạn không làm là xem xét một thể hiện của một lớp học:

p Object.new.class 
p Hello.new.class 

Các lớp xác định dạng của một đối tượng và theo định nghĩa, một lớp là một lớp. Nhưng khi bạn khởi tạo lớp vào một đối tượng, đối tượng là kiểu mới. Nhưng bạn vẫn có thể thấy rằng lớp của đối tượng là thân Class:

p Hello.new.class.class 
+0

câu cuối cùng của bạn có lẽ nên được "... mà lớp lớp của các đối tượng là bản thân 'Class'" hoặc "... rằng lớp của đối tượng là chính nó một (n instance of) 'Class'" –

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