2012-12-04 37 views

Trả lời

48

Trái với các ngôn ngữ khác, Ruby không có phương thức lớp, nhưng nó có phương thức đơn được gắn với một đối tượng cụ thể.

cat = String.new("cat") 
def cat.speak 
    'miaow' 
end 
cat.speak #=> "miaow" 
cat.singleton_methods #=> ["speak"] 

def cat.speak đã tạo một phương thức đơn lẻ gắn liền với đối tượng mèo.

Khi bạn viết class A, nó tương đương với A = Class.new:

A = Class.new 
def A.speak 
    "I'm class A" 
end 
A.speak #=> "I'm class A" 
A.singleton_methods #=> ["speak"] 

def A.speak đã tạo ra một phương pháp singleton thuộc đối tượng A. Chúng tôi sử dụng để gọi nó là một phương pháp của lớp A.

Khi bạn viết

class A 
    def self.c_method 
     'in A#c_method' 
    end 
end 

bạn tạo một thể hiện của lớp (*).Bên trong định nghĩa lớp, Ruby đặt bản thân thành thể hiện mới của Class, đã được gán cho hằng số A. Vì vậy, def self.c_method tương đương với def cat.speak, tức là bạn định nghĩa một phương thức singleton gắn liền với đối tượng tự, mà hiện tại là lớp A.

Bây giờ lớp A có hai phương thức đơn, mà chúng ta thường gọi phương thức lớp.

A.singleton_methods 
=> ["c_method", "speak"] 

(*) về mặt kỹ thuật, trong trường hợp này đó A đã được tạo ra bởi A = Class.new, class A mở lại các lớp học hiện có. Đó là lý do tại sao chúng tôi có hai phương pháp singleton ở cuối. Nhưng trong trường hợp thông thường, đó là định nghĩa đầu tiên của một lớp, nó có nghĩa là Class.new.

+6

Đây là câu trả lời đúng. Đúng là các nhà Rubyist có kinh nghiệm đôi khi sử dụng thuật ngữ "class method" để ngụ ý "instance method của class singleton class của đối tượng class", nhưng chúng chỉ sử dụng thuật toán đó trong sự hiểu biết đầy đủ rằng * không có thứ gì như method class * trong Ruby. (Trên thực tế, không có phương thức như "phương pháp singleton" hoặc: phương thức singleton chỉ là các phương thức thông thường được xác định trong lớp đơn của một đối tượng.) OP, tuy nhiên, rõ ràng là * không * một người theo kinh nghiệm Rubyist , do đó gây nhầm lẫn anh ta với viết tắt không phải là một ý tưởng tốt. Thumbs up! –

7

Khi khai báo một phương thức, self của khai báo là lớp/mô-đun khai báo, vì vậy hiệu quả bạn định nghĩa một phương thức lớp. Điều này giống như phương thức static trong java. Bạn sẽ gọi phương thức trên lớp thay vì một cá thể: MyClass.method

Here bạn có thể tìm thêm một số chi tiết về phương pháp lớp và thể hiện.

EDIT: Trong khi từ khóa self giống như từ khóa this trong java, tác dụng của việc sử dụng self để khai báo phương thức lớp tương tự như ảnh hưởng của việc sử dụng từ khóa static trong java. Sự tương tự là các phương thức tĩnh trong java, giống như các phương thức lớp trong ruby ​​được truy cập bằng cách sử dụng đối tượng lớp là chính nó thay vì một cá thể của lớp.

Xin lưu ý rằng static không đứng đối diện với động. Việc lựa chọn tên cho từ khóa này là có vấn đề (có thể được kế thừa từ C) và thay vào đó nên được gọi là perClass hoặc tương tự để phản ánh tốt hơn ý nghĩa. Ý nghĩa kỹ thuật là tất cả các thành viên static chỉ tồn tại một lần cho mỗi trình nạp lớp.

+1

Đó là * không có gì * giống như 'tĩnh'. Đặc biệt, những phương thức đó là động, không tĩnh. –

+3

@ JörgWMittag: nó giống như 'static' của Java trong ít nhất một nghĩa - nó áp dụng cho cấp lớp chứ không phải cấp độ cá thể. –

+3

@ JörgWMittag - là một thuật ngữ khá mạnh mẽ cho một cái gì đó có điểm tương đồng khác biệt (và chắc chắn có sự khác biệt). đã thêm một số thông tin để làm rõ quan điểm của tôi. – kostja

29

Trong bản thân ruby ​​có phần tương tự như this trong java, nhưng khi nói đến các lớp, nó giống với từ khóa static trong java. Một ví dụ nhỏ:

class A 
    # class method 
    def self.c_method 
    true 
    end 
    # instance method 
    def i_method 
    true 
    end 
end 

A.c_method #=> true 
A.i_method #=> failure 
A.new.i_method #=> true 
A.new.c_method #=> failure 

Cập nhật: khác biệt giữa các phương pháp tĩnh trong java và lớp phương pháp trong ruby ​​

phương pháp tĩnh trong Java có hai tính năng riêng biệt mà làm cho họ khác biệt so với phương pháp dụ: a) chúng là tĩnh, b) chúng không liên kết với một cá thể. (IOW: chúng thực sự không giống như các phương thức, chúng chỉ là các thủ tục.) Trong Ruby, tất cả các phương thức đều là động và tất cả các phương thức đều được liên kết với một cá thể. Trong thực tế, không giống như Java, nơi có ba loại khác nhau của "phương thức" (các phương thức ví dụ, các phương thức tĩnh và các hàm tạo), chỉ có một kiểu phương thức trong các phương thức của Ruby: instance. Vì vậy, không: các phương thức tĩnh trong Java hoàn toàn khác với các phương thức trong Ruby. - Jörg W Mittag 1 giờ trước

+0

Đó là * không có gì * giống như 'tĩnh'. Đặc biệt, những phương thức đó là động, không tĩnh. –

+0

nếu bạn định nghĩa một phương thức 'Class #' trong ruby ​​với def' self.method ... 'kiểu của nó giống như' lớp JavaClass; phương thức static static public ... 'trong java – krichard

+2

Các phương thức tĩnh trong Java có hai tính năng riêng biệt làm cho chúng khác với các phương thức ví dụ: a) chúng là tĩnh, b) chúng không liên kết với một cá thể. (IOW: chúng thực sự không giống như các phương thức * *), chúng chỉ là các thủ tục.) Trong Ruby, * tất cả các phương thức * là động và các phương thức * all * được liên kết với một cá thể. Trong thực tế, không giống như Java, nơi có ba loại khác nhau của "phương thức" (các phương thức ví dụ, các phương thức tĩnh và các hàm tạo), chỉ có * một kiểu phương thức trong các phương thức của Ruby: instance. Vì vậy, không: các phương thức tĩnh trong Java hoàn toàn khác với các phương thức trong Ruby. –