일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- dynamic programming
- Matrix
- 코딩테스트
- geometry
- two pointers
- 구현
- greedy
- Tree
- 코테
- SQL
- implement
- array
- simulation
- Binary Tree
- Stack
- Binary Search
- Number Theory
- 파이썬
- string
- Math
- Counting
- hash table
- 자바
- sorting
- database
- Data Structure
- Method
- Class
- bit manipulation
- java
- Today
- Total
코린이의 소소한 공부노트
메서드 오버로딩 본문
일반적으로 메서드는 1가지 기능만 하게 만드는 것이 보통이고, 이 기능을 잘 표현하는 메서드 이름을 붙이기 때문에 메서드와 메서드 이름이 1:1 매칭이 되게 만든다.
int add(int x, int y) { return x+y; }
위의 예시는 int끼리 더하는 메서드이다. 그런데 더하는 건 short이나 double도 할 수 있다. short은 계산 시 int로 자동 형변환이 되니까 add를 사용할 수 있다고 쳐도, double은 int보다 큰 타입이기 때문에 매개변수가 int로 선언된 add를 사용할 수 없다. double을 위한 메서드도 만들어줘야 한다.
double addDouble(double x, double y) { return x+y; }
그런데 가만 생각해보면, double이든 int든 결국 덧셈 연산을 하는 것은 똑같다. 타입이 다르다고 같은 일을 하는 메서드를 타입마다 다 만드는 것도 상당히 마음에 들지 않는다. 그리고 각 타입마다 메서드 이름도 달리 해야 하는 것도 꽤 귀찮은 일이다. 이를 해결해주는 것이 바로 메서드 오버로딩이다.
메서드 오버로딩은 한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것이다. 우리가 아주 잘 알고 있는 println 메서드가 대표적인 메서드 오버로딩의 예시다. 3가지만 확인해보겠다.
void println()
void println(int x)
void println(String x)
println 메서드는 매개변수가 있다면 그 값을 출력하고 줄 바꿈을 해준다. 위 3가지는 같은 일을 하는데 단지 매개변수의 차이만 있을 뿐이다. 사람이 생각할 때는 내용이 뭐든 받아서 출력만 하면 된다고 생각하겠지만 컴퓨터는 그렇지 않다. 컴파일 단계에서 타입을 모두 확인하기 때문에 매개변수의 타입이 다르면 바로 에러를 낸다. 이러한 관점에서 본다면 메서드 오버로딩은 사람이 자연스럽게 생각하고 받아들이는 것을 그대로 구현해주는 작업이다.
[오버로딩이 성립하기 위한 조건]
1. 메서드 이름이 같아야 한다.
- 같은 작업을 하는 메서드를 오버로딩하는 것이기 때문에 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
- 같은 타입이고 개수도 같으면 메서드 중복 정의이다.
3. 반환 타입은 상관 없다.
예시 코드를 하나씩 보며 오버로딩인지 중복 정의인지 확인해보자.
// 1.
int add(int a, int b) { return a+b; }
int add(int x, int y) { return x+y; }
1) 메서드 이름이 같다. -> ok
2) 매개변수의 타입, 개수가 같다. -> stop
-> 이것은 오버로딩X, 중복정의O -> error: The method add(int, int) is already defined
// 2.
int add(int a, int b) { return a+b; }
long add(int a, int b) { return a+b; }
1) 메서드 이름이 같다. -> ok
2) 매개변수의 타입, 개수가 같다. -> stop
-> 이것은 오버로딩X, 중복정의O -> error: Duplicate method add(int, int)
-> 반환 타입이 다른 것은 오버로딩 성립과 관계없음
-> 1번과 2번은 에러 메세지만 다를 뿐 같은 에러
// 3.
int add(int a, long b) { return (int)(a+b); }
long add(long a, int b) { return a+b; }
1) 메서드 이름이 같다. -> ok
2) 매개변수의 개수는 같지만 타입이 다르다. -> ok
-> 오버로딩 성립
-> 그러나 첫 번째 메서드에서 a+b가 int의 범위를 초과하면 오버플로우가 발생할 수 있음
3번만 오버로딩이 성립한다. 매개변수의 개수는 같지만 첫번째 메서드는 int, long 순서이고 두번째 메서드는 long, int순서라 타입이 달라 오버로딩 성립 조건에 해당한다. 그런데 3번처럼 쓰고 실제로 메인에서 메서드 호출을 하게 되면 에러가 발생한다.
class Mathfunc {
int add(int a, long b) { return (int)(a+b); }
long add(long a, int b) { return a+b; }
}
class Test{
public static void main(String args[]) {
Mathfunc mf = newMathfunc();
// 1) int, int
System.out.println(mf.add(3,3)); // error: The method add(int, long) is ambiguous for the type Mathfunc
// 2) long, int
System.out.println(mf.add(3L,3); // 6
// 3) int, long
System.out.println(mf.add(3,3L)); // 6
// 4) long, long
System.out.println(mf.add(3L,3L)); // error: The method add(long, int) in the type Mathfunc is not applicable for the arguments (long, long)
}
}
1) 매개변수로 int와 int가 넘어간 상황
- 첫 번째 메서드 int add(int a, long b)의 입장: 두 번째 int가 long으로 자동 형변환됨 -> ok
- 두 번째 메서드 long add(long a, int b)의 입장: 첫 번째 int가 long으로 자동 형변환됨 -> ok
-> 두 메서드 중 무엇을 써야 할지 모호하기(ambiguous) 때문에 에러 발생
2) 매개변수로 long과 int가 넘어간 상황
- 두 번째 메서드 long add(long a, int b) 호출 -> 3+3 = 6 반환
- println에서 6 출력
3) 매개변수로 int와 long이 넘어간 상황
- 첫 번째 메서드 int add(int a, long b) 호출 -> 3+3 = 6 반환
- println에서 6 출력
4) 매개변수로 long과 long이 넘어간 상황
- 첫 번째 메서드 int add(int a, long b)의 입장: 첫 번째 long이 걸림 -> pass
- 두 번째 메서드 long add(long a, int b)의 입장: 두 번째 long이 걸림 -> pass
-> 적용 가능한 메서드가 없어(not applicable) 에러 발생
오버로딩을 이용할 때 성립 조건에 부합하는지 확인하고, 형변환도 고려해보는 것이 좋다.
'Java' 카테고리의 다른 글
생성자 this() vs 참조변수 this (0) | 2022.03.12 |
---|---|
생성자 (0) | 2022.03.12 |
스태틱/인스턴스 메서드 (0) | 2022.03.07 |
메서드의 매개변수 (0) | 2022.03.06 |
메서드의 호출 스택 (0) | 2022.03.05 |