오버로딩(Overloading)

2 분 소요

메서드도 변수와 마찬가지로 같은 클래스 내에서 서로 구별되어야 하기에 고유한 이름을 가져야한다. 하지만 자바에서는 매개변수의 개수나 타입이 다르다면 한 클래스 내에 이미 존재하는 이름과 같은 이름을 가진 메서드를 정의할 수 있다. 이와 같이 한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것을 메서드 오버로딩이라고 한다. 오버로딩(Overloading)의 사전적 의미는 과적하다로 많이 싣는 것을 뜻한다. 이는 하나의 이름으로 여러 기능을 구현하기 때문에 붙여진 이름이라 생각할 수 있다.

오버로딩의 조건

  • 같은 이름의 메서드를 정의하는 것만으로 오버로딩인 것이 아니다.
    1. 메서드 이름이 같아야 한다.
    2. 매개변수의 개수 또는 타입이 달라야 한다.
  • 메서드의 이름이 같더라도 매개변수의 정의가 다르면 메서드를 구분할 수 있기에 오버로딩이 가능한 것이다.
  • 위의 조건을 만족하지 못하는 메서드는 중복 정의로 간주되어 컴파일 에러를 발생시킨다.
  • 오버로딩된 메서드는 매개변수에 의해 구별되므로 반환타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.

오버로딩의 예시

  • 그 동안 화면에 출력을 할때 사용하던 println메서드가 그 예이다.
  • PrintStream클래스는 어떤 타입의 매개변수를 지정해도 출력이 가능하도록 10개의 오버로딩된 println 메서드를 포함한다.

오버로딩의 장점

  • 만약 메서드가 변수와 같이 오직 이름으로만 구별된다면, 앞서 살펴보았던 println메서드는 10개의 각기 다른 이름을 가져야 한다.
  • 근본적으로 같은 기능을 하는 메서드들이 서로 다른 이름을 가져야 하기에 개발자는 각 메서드의 네이밍의 수고를 감수해야한다.
  • 사용자 또한 이름으로 메서드를 구분하여 기억해야하는 번거로움이 있다.
  • 오버로딩을 통해 다른 여러 메서드들이 하나의 이름으로 정의될 수 있기에 하나의 메서드만 기억하면 되므로 기억하기 쉽고, 네이밍도 간편하다.
  • 하나의 이름으로 여러 메서드를 정의할 수 있으므로, 메서드의 이름을 절약할 수 있다.
    • 동시에 사용되었어야 할 메서드의 이름을 다른 메서드의 이름으로 사용할 수 있다.

가변인자와 오버로딩

  • 기존에는 메서드의 매개변수 개수가 고정적이었으나, JDK1.5부터 동적으로 지정해 줄 수 있게 되었다.
    • 가변인자(variable arguments)
    • 가변인자는 타입... 변수명과 같은 형식으로 선언하며, PrintStream클래스의 printf()가 대표적 예이다.
      public PrintStream printf (String format, Object... args){ ... }
      
    • 위와 같이 가변인자 외에도 매개변수가 더 있다면, 가변인자를 매개변수 중 가장 마지막에 선언해야 한다.
    • 그렇지 않을 시, 가변인자인지 아닌지 구별할 수 없기 때문에 컴파일 에러가 발생한다.
  • 여러 문자열을 하나로 결합하여 반환하는 concatenate메서드를 작성한다면 아래와 같이 매개변수를 다르게 하여 여러 메서드를 작성해야 한다.
    String concatenate(String s1, String s2){ ... }
    String concatenate(String s1, String s2, String s3){ ... }
    String concatenate(String s1, String s2, String s3, Stirng s4){ ... }
    
  • 하지만, 아래와 같이 가변인자를 사용하면 하나의 메서드로 대체할 수 있다.
    String concatenate(String... str) { ... }
    
  • 이 메서드를 호출할 때는 인자의 개수를 가변적으로 할 수 있고, 심지어는 인자가 없거나 배열도 인자가 될 수 있다.
    concatenate();
    concatenate("a");
    concatenate("a", "b");
    concatenate(new String[]{"a", "b"});
    concatenate({"a", "b"}) <- 불가
    
  • 위의 마지막 예와 같이 가변인자는 내부적으로 배열을 이용한다.
  • 따라서 가변인자가 선언된 메서드를 호출할 때마다 배열이 새로 생성된다.
  • 가변인자가 편리하지만, 이러한 비효율이 숨어있으므로 꼭 필요한 경우에만 사용하는 것이 좋겠다.
  • 메서드의 매개변수를 가변인자가 아닌 배열로 처리한다면 반드시 인자를 정의해야하기 때문에 null이나 빈 배열을 지정해야 한다.

가변인자의 오버로딩

가변인자를 매개변수로 받는 메서드를 오버라이딩하면 구분되지 않는 경우가 발생하기 때문에, 가능하면 가변인자를 사용한 메서드는 오버로딩하지 않는 것이 좋다.

1 1

댓글남기기