Skip to content

[Ruby] Instance(實例) vs Class(類別) variable 差別是什麼

Published: at 11:50 AM (3 min read)

在面試 RoR 時,Instance(實例)Class(類別) variable 的差異算是蠻常見的問題,但一陣子沒寫 Ruby 一時又忘記了…因此記錄一下讓自己之後可以回來複習 🥲

Class(類別) Variable

語法表示為 @@var,代表這個變數是屬於類別本身及其子類別所共用的變數,可以想像為 singleton(單例) 模式,不管你從哪個子類別去存取這個變數,都會是同一個值。

直接來看個範例(類別變數會在繼承中共享):

  # 假設你有不同類別代表不同種類的訂單,但需要一個統整的總訂單數
  class Order
    @@total_orders = 0

    def initialize
      @@total_orders += 1
    end

    def self.total_orders
      @@total_orders
    end
  end

  class OnlineOrder < Order; end
  class StoreOrder < Order; end

  10.times { OnlineOrder.new }
  5.times  { StoreOrder.new }

  puts Order.total_orders       # => 15 (類別變數 @@total_orders,在繼承樹中共享)
  puts OnlineOrder.total_orders # => 15 (類別變數 @@total_orders,在繼承樹中共享)
  puts StoreOrder.total_orders  # => 15 (類別變數 @@total_orders,在繼承樹中共享)

Instance(實例) Variable

語法表示為 @var,代表這個變數是屬於類別物件本身的,每個物件都有一個自己的變數,因此你可以在此維護每個物件的狀態,不會被其他物件影響。

一樣來看個範例(實例變數屬於個別物件):

class Order
  @@total_orders = 0
  attr_reader :item_count

  def initialize(item_count = 0)
    @item_count = item_count
    @@total_orders += 1
  end

  def self.total_orders
    @@total_orders
  end
end

class OnlineOrder < Order; end
class StoreOrder < Order; end

online_order = OnlineOrder.new(10)
store_order  = StoreOrder.new(5)

puts online_order.item_count   # => 10 (實例變數 @item_count 在每個物件中獨立)
puts store_order.item_count    # => 5  (實例變數 @item_count 在每個物件中獨立)
puts Order.total_orders        # => 2 (類別變數 @@total_orders,在繼承樹中共享)
puts OnlineOrder.total_orders  # => 2  (類別變數 @@total_orders,在繼承樹中共享))
puts StoreOrder.total_orders   # => 2  (類別變數 @@total_orders,在繼承樹中共享)

總結

參考資料


Previous Post
[LeetCode] 69. Sqrt(x)
Next Post
[LeetCode] 66. Plus One