多載¶
我們可以定義一個 become_older
方法,它接受一個數字來表示要成長的年數。
class Person
getter :age
def initialize(@name : String, @age : Int = 0)
end
def become_older
@age += 1
end
def become_older(years)
@age += years
end
end
john = Person.new "John"
john.age # => 0
john.become_older
john.age # => 1
john.become_older 5
john.age # => 6
也就是說,您可以擁有相同名稱但參數數量不同的方法,它們會被視為獨立的方法。這稱為方法多載。
方法會根據以下幾個標準進行多載:
- 參數的數量
- 套用至參數的類型限制
- 必要的具名參數的名稱
- 方法是否接受區塊
例如,我們可以定義四個不同的 become_older
方法
class Person
@age = 0
# Increases age by one
def become_older
@age += 1
end
# Increases age by the given number of years
def become_older(years : Int32)
@age += years
end
# Increases age by the given number of years, as a String
def become_older(years : String)
@age += years.to_i
end
# Yields the current age of this person and increases
# its age by the value returned by the block
def become_older(&)
@age += yield @age
end
end
person = Person.new "John"
person.become_older
person.age # => 1
person.become_older 5
person.age # => 6
person.become_older "12"
person.age # => 18
person.become_older do |current_age|
current_age < 20 ? 10 : 30
end
person.age # => 28
請注意,在會 yield 的方法的情況下,編譯器會判斷出來,因為有 yield
表達式。為了更明確地表示,您可以在最後新增一個虛擬的 &block
參數
class Person
@age = 0
def become_older(&block)
@age += yield @age
end
end
在產生的文件中,無論您是否編寫,都會永遠顯示虛擬的 &block
方法。
在參數數量相同的情況下,編譯器會嘗試對它們進行排序,將限制較少的方法放在最後。
class Person
@age = 0
# First, this method is defined
def become_older(age)
@age += age
end
# Since "String" is more restrictive than no restriction
# at all, the compiler puts this method before the previous
# one when considering which overload matches.
def become_older(age : String)
@age += age.to_i
end
end
person = Person.new "John"
# Invokes the first definition
person.become_older 20
# Invokes the second definition
person.become_older "12"
但是,編譯器並非總是能夠判斷出順序,因為並非總是存在全序關係,因此最好始終將限制較少的方法放在最後。