메서드 오버로딩을 이해하기 위해서는 먼저 메서드 시그너처mathod signature의 의미를 알아야 한다.메서드 시그너처는 메서드명과 입력매개변수의 자료형을 말한다. 시그너처(서멍)라는 말에서 유추할 수 있듯이메서드를 구분하는 기준 역할을 한다. 자바 가상 머신은 메서드 시그너처가 다르면 메서드명이 동일해도 다른 메서드로 인식한다.메서드 오버로딩 method overloading 은 이러한 특징을 이용한 것으로 입력매개변수의 개수나 자료형이 다른 여러 개의 동일한 이름을 지닌 메서드를 같은 공간에 정의하는 것을 말한다.
🐯메서드 오버로딩
리턴 타입 메서드명 (자료형 변수명, 자료형 변수명,...) {
} // 메서드명, 자료형, 자료형 -> 메서드 시그너처
예
int sum(int a, int b) {
return 3;
}
//sum, int, int -> 메서드 시그너처
오버로딩된 메서드의 호출은 앞에서 배운 메서드의 호출과 전혀 다를 게 없다. 다만 동일한 이름의 메서드가 많기 때문에입력매개변수에 따라 실제 어떤 메서드가 호출된 것인지만 구분해주면 된다.
앞의 예제를 살펴보면 4개의 print() 메서드가 오버로딩돼 있으며, 각각은 서로 다른 입력매개변수의 개수나 타입을 포함하고 있다는 것을 알 수 있다. 즉 , 서로 다른 메서드 시그너처를 지니고 있다. 따라서 호출할 때 넘겨주는 입력매개변수에 따라 호출될 메서드가 선택된다. 그동안 우리는 화면 출력을 위해 System.out.println() 메서드를 많이 사용해 왔다. 자바 API 문서에서 println() 메서드를 살펴보면 다음과 같이 무려 10개의 메서드가 오버로딩된 것을 알 수 있다. 그래서 출력할 때 정수와 실수 그리고 문자열도 잘 출력됐던 것이다.
왜 시그너처에 리턴 타입이 빠져있을까? 리턴 타입이 빠져 있는 이유는 메서드를 호출할 때 리턴 타입을 명시하지 않기 때문이다.
public static void main (String[] ar) {
print(3); // ?
}
public static void print(int a) {
// ...
}
public static int print(int a) {
// ...
}
// 두 시그니처가 동일하므로 오버로딩 불가능
리턴 타입이 다른 두 개의 print()메서드를 생성했다. 메서드를 호출하기 위해 print(3)을 호출하면 이 2개의 메서드 중 무엇을 실행해야 할까? 호출 과정에서 리턴 타입을 사용하지 않으므로 리턴 타입으로는 메서드를 구분할 수 없는 것이다. 이것이 바로 리턴 타입이 시그너처에 포함되지 않은 이유다.
실습
public class jh {
public static void main(String[] args) {
print();
print(3);
print(5.8);
print(2,5);
//서로 다른 시그너처를 지니고 있는 print() 메서드를 입력매개변수에 따라 호출
}
public static void print() {
System.out.println("데이터가 없습니다.");
}
public static void print(int a) {
System.out.println(a);
}
public static void print(double a) {
System.out.println(a);
}
/* public static void print(double b){
System.out.println(b);*/ // void print(double a){}와 중복으로 정의 불가능
public static void print(int a, int b) {
System.out.println("a: " + a + " b :" + b);
}
/* public static int print(int a, int b){
System.out.println("a :" + a + "b: "+ b);
return a + b;*/ // void print(int a, int b){}와 중복으로 정의 불가능
}