跳轉到內容

Ruby 程式設計/類和物件

來自華夏公益教科書,開放的書籍,開放的世界

← 編寫方法 | 異常 →


如前所述,Ruby 中的一切都是物件。每個物件都有一個類。要查詢物件的類,只需呼叫該物件的class方法。例如,試試這個

    puts "This is a string".class
    puts 9.class
    puts ["this","is","an","array"].class
    puts ({:this => "is", :a => "hash"}).class
    puts :symbol.class

無論如何,你應該已經知道這一點。然而,你不知道的是如何建立自己的類和擴充套件 Ruby 的類。

建立類的例項

[編輯 | 編輯原始碼]

類的例項是屬於該類的物件。例如,"巧克力"是 String 類的例項。你已經知道你可以透過簡單地使用引號、方括號、花括號等來建立字串、陣列、雜湊、數字和其他內建型別,但你也可以透過new方法來建立它們。例如,my_string = ""my_string = String.new相同。幾乎每個類都有一個new方法:陣列、雜湊,等等。(一些類,比如整數和數字,沒有new方法。這些類不允許在例項化物件之間存在重複。)當你建立自己的類時,你會使用new方法來建立例項。

建立類

[編輯 | 編輯原始碼]

類代表物件的型別,例如書籍、鯨魚、葡萄或巧克力。每個人都喜歡巧克力(可能不正確),所以讓我們建立一個巧克力類

    class Chocolate
      def eat
        puts "That tasted great!"
      end
    end

讓我們看一下。類是透過class關鍵字建立的。之後是類的名稱。所有類名必須以大寫字母開頭。按照慣例,我們對類名使用駝峰式命名法。所以我們會建立像 PieceOfChocolate 這樣的類,而不是像 Piece_of_Chocolate 這樣的類。

下一節定義了一個類方法。類方法是為特定類定義的方法。例如,String 類具有length方法

    # outputs "5"
    puts "hello".length

要呼叫 Chocolate 類例項的eat方法,我們將使用此程式碼

    my_chocolate = Chocolate.new
    my_chocolate.eat # outputs "That tasted great!"

你也可以使用send

    "hello".send(:length) # outputs "5"
    my_chocolate.send(:eat) # outputs "That tasted great!"

來呼叫方法。然而,使用send很少見,除非你需要建立動態行為,因為我們不需要將方法名指定為文字 - 它可以是一個變數。

請注意,Ruby 中方法的典型定義以關鍵字 def 開頭。

但是,你也可以使用 define_method() 代替,並將它與 .send 結合起來,來呼叫任意方法

  class Foo
    self.class_eval {
      define_method(:'hey there') { puts 'Hey there man!' }
    }
  end
  foo = Foo.new
  foo.send :'hey there' # => Hey there man!

在類的某個方法內部,偽變數self(偽變數是不能更改的變數)指的是當前例項。例如

    class Integer
      def more
        return self + 1
      end
    end
    3.more # -> 4
    7.more # -> 8

類方法

[編輯 | 編輯原始碼]

你也可以建立在類而不是例項上呼叫的方法。例如

    class Strawberry
      def Strawberry.color
        return "red"
      end
 
      def self.size
        return "kinda small"
      end
 
      class << self
        def shape
          return "strawberry-ish"
        end
      end
    end
    Strawberry.color # -> "red"
    Strawberry.size  # -> "kinda small"
    Strawberry.shape # -> "strawberry-ish"

請注意三種不同的構造ClassName.method_nameself.method_name本質上是相同的 - 在類塊中的方法定義之外,self指的是類本身。後者是首選,因為它使更改類名變得容易得多。最後一個構造,class << self,將我們置於類的“元類”(有時稱為“本類”)的上下文中。元類是類本身所屬的特殊類。但是,在這一點上,你無需擔心它。此構造所做的只是允許我們在沒有self.字首的情況下定義方法。

華夏公益教科書