오버로딩

몇 살이나 나이를 먹을지를 인자로 받는 become_older 메서드를 정의할 수 있습니다.

class Person
  @age = 0

  def become_older
    @age += 1
  end

  def become_older(years)
    @age += years
  end
end

cholsu = Person.new "철수"
cholsu.age #=> 0

cholsu.become_older
cholsu.age #=> 1

cholsu.become_older 5
cholsu.age #=> 6

즉, 이름이 같지만 다른 인자를 받는 메서드를 정의할 수 있습니다. 이 둘은 별도의 메서드로 취급됩니다. 이런 경우를 가리켜 메서드 오버로딩이라고 합니다.

메서드 오버로드에는 몇 가지 기준이 있습니다.

  • 인자의 개수
  • 인자에 적용된 타입 제약
  • 이름 달린 인자 중 필수적인 인자들의 이름
  • 메서드가 블락을 받는지 여부

예를 들어, 서로 다른 네 가지의 become_older 메서드를 정의할 수 있습니다.

class Person
  @age = 0

  # 나이를 한 살 먹기
  def become_older
    @age += 1
  end

  # 나이를 주어진 만큼 먹기
  def become_older(years : Int32)
    @age += years
  end

  # 나이를 문자열로 주어진 만큼 먹기
  def become_older(years : String)
    @age += years.to_i
  end

  # 이 사람의 현재 나이를 블락에 넘겨서
  # 블락이 반환한 만큼 나이를 먹기
  def become_older
    @age += yield @age
  end
end

person = Person.new "철수"

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에 의해 구분된다는 것을 볼 수 있습니다. 마지막에 의미 없는 &block 인자를 추가함으로써 이를 명시적으로 나타낼 수 있습니다.

class Person
  @age = 0

  def become_older(&block)
    @age += yield @age
  end
end

자동으로 생성되는 문서에서는 이 &block 인자가 명시하지 않더라도 항상 나타날 것입니다.

인자의 개수가 같다면 컴파일러는 제약이 많은 순서로 정렬합니다.

class Person
  @age = 0

  # 이 메서드가 우선 정의됨
  def become_older(age)
    @age += age
  end

  # 제약이 아예 없는 것보다 "String"은 제약이 더 많은 셈이므로,
  # 컴파일러는 어떤 오버로드가 사용될지 결정할 때
  # 이 메서드를 앞서 정의한 것보다 우선으로 고려합니다.
  def become_older(age : String)
    @age += age.to_i
  end
end

person = Person.new "철수"

# 첫 번째 정의를 호출
person.become_older 20

# 두 번째 정의를 호출
person.become_older "12"

하지만 완전한 순서가 있어서 컴파일러가 순서를 항상 알아낼 수 있는 것은 아니기 때문에, 제약이 더 많은 메서드를 앞에, 제약이 더 적는 메서드를 뒤에 두는 것이 좋은 습관입니다.

results matching ""

    No results matching ""