오버로딩의 의미
메서드도 변수와 마찬가지로 같은 클래스 내에서 서로 구별될 수 있어야 하기 때문에 각기 다른 이름을 가져야 한다.
자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은이름을 사용해서 메서드를 정의할 수 있다.
이 처럼, 한 클래스 내에서 같은 이름의 메서드를 여러 개 정의하는 것을 '메서드 오버로딩method overloading)또는 간단히 오버로딩(overloading)이라 한다.
오버로딩의 조건
같은 이름의 메서드를 정의한다고 해서 무조건 오버로딩인 것은 아니며, 다음조건을 만족해야한다.
1. 메서드 이름이 같아야 한다
2. 매개변수의 개수 또는 타입이 달라야 한다.
메서드의 이름이 같다 하더라도 매개변수가 다르면 서로 구별될 수 있기 때문에 오버로딩이 가능한 것이다.
오버로딩된 메서드들은 매개변수에 의해서만 구별될 수 있으므로 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
오버로딩의 예
오버로딩의 예로 가장 대표적인 것은 println메서드이다. println메서드를 호출할 때 매개변수로 지정하는 값의 타입에 따라서 호출되는 println메서드가 달라진다.
PrintStream클래스에는 어떤 종류의 매개변수를 지정해도 출력할 수 있도록 아래와 같이 10개의 오버로딩된 printlon메서드를 정의해놓고 있다.
void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(Object x)
void println(String x)
println메서드를 호출할 때 매개변수로 넘겨주는 값의 타입에 따라서 위의 오버로딩된 메서드들 중의 하나가 선택되어 실행된다.
int add(ina a, int b) { return a+b; }
int add(int x, int y) { return x+y; }
이것은 매개변수의 이름만 다를 뿐 매개변수의 타입이 같기 때문에 오버로딩이 아니다.
컴파일 시 add(int,int) is already defined라는 에러가 난다.
int add(int a, int b) { return a+b; }
long add(int a, int b) {return (long)(a + b); }
매개변수의 타입과 개수가 일치하기 때문에 어떤 메서드가 호출된 것인지 결정할 수 엇ㅂ기 때문에 오버로딩으로 간주되지 않고 add(int,int) is already defined라는 컴파일 에러가 난다.
long add(int a, long b) { return a+b; }
long add(long a, int b) { return a+b; }
두 메서드 모두 int형과 long형 매개변수가 하나씩 선언되어 있지만, 서로 순서가 다른 경우이다.
이 경우에 호출 시 매개변수의 값에 의해 호출될 메서드가 구분될 수 있으므로 중복된 메서드 정의가 아닌, 오버로딩으로 간주한다.
int add(int a, itn b)
long add(long a, long b)
long add(int[] a) {
long result = 0;
for(int i = 0; i < a.length; i++) {
result += a[i];
}
return result
}
위 메서드들은 모두 바르게 오버로딩되어 있다.
오버로딩의 장점
void println()
void printlnBoolean(boolean x_
void printlonChar(char x)
void printlnDouble(double x)
void printlnString(String x)
근본적으로 같은 기능을 하는 메서드들이지만 서로 다른 이름을 가져야 하기 때문에 메서드를 작성하는 쪽에서는 이름을 짓기도 어렵고, 메서드를 사용하는 쪽에서느 이름을 일일이 구분해서 기억하기때문에 부담이 되는데, 오버로딩을 사용하면 부담이 줄어든다.
기억하기도 쉽고 이름도 짧게 가능하고 이름만보고 메서드들의 기능이 같겠구나 하는 짐작도 쉽게 가능하며 메서드의 이름을 절약할 수 있다.
가변인자(varargs)와 오버로딩
매개변수의 개수를 유동적으로 지정하는것을 가변인자(variable arguments)라고한다.
가변인자는 '타입... 변수명'과 같은 형식으로 선언한다.
public PrintStream printf(String format, Object... args) {...}
위와 같이 가변인자 외에도 매개변수가 더 있다면, 가변인자를 매개변수 중에서 제일 마지막에 선언해야 한다.
가변인자인지 아닌지 구별할 방법이 없기 때문에 허용하지 않는 것이다.
가변인자는 내부적으로 배열을 이용하는것이다. 그래서 가변인자가 선언된 메서드를 호출할 때 마다 배열이 새로 생성된다.
C언어와는 달리 자바에서는 길이가 0인 배열을 생성하는 것이 허용된다.
public class VarArgsEx {
public static void main(String[] args) {
String[] strArr = { "100", "200", "300" };
System.out.println(concatenate("", "100", "200", "300"));
System.out.println(concatenate("-", strArr));
System.out.println(concatenate(",", new String[] {"1", "2", "3"}));
System.out.println("["+concatenate(",", new String[0])+"]");
System.out.println("["+concatenate(",")+"]");
}
static String concatenate(String delim, String...args) {
String result = "";
for(String str : args) {
result += str + delim;
}
return result;
}
//
// static String concatenate(String...strings args) {
// return concatenate("", args);
// }
}
100200300
100-200-300-
1,2,3,
[]
[]