오버로딩과 오버라이딩..
얼핏보면 비슷해보이는데 둘이 뭐가 다른걸까??
철자가 다르긴 한데
우선 하나씩 알아가보도록 하자.
overloading
)" 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것 "
▶ 마치 하나 이상(over)의 동일명 메서드가 있더라도 사용/컴파일(loading)할 수 있다는 것
메서드는 변수와 마찬가지로
" 같은 클래스 내에서 서로 구별될 수 있어야 한다. "
그렇기 때문에
각자 다른 이름을 가져야하는데
자바에서는
한 클래스 내에
" 이미 사용하려는 이름과 동일한 이름의 메서드가 있더라도 "
매개변수의 개수 / 타입이 다르다면
같은 이름을 사용해서 정의할 수 있다.
즉 같은 이름을 가진 메서드이더라도
매개변수를 근거로 분류하는 것이다.
( 그래서 변환 타입은 관계가 없는 것이다. )
※ 조건
- 메서드 이름 동일
- 매개변수의 개수 또는 타입이 달라야함
( 둘 중 하나만 달라도 된다. 게다가 유무有無로도 오버로딩 가능)- 변환 타입은 관계 없음.
예를 들면 println
메서드가 있는데
우리가 실제로 해당 메서드를 어떠한 값이든 지정해주면 출력되었다.
아무런 문제가 발생하지 않았던 이유가
// PrintStream 클래스
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
메서드를 정의해 놓았기 때문이다.
그래서 이 메서드를 호출할 때
매개변수로 넘겨주는 값 타입에 따라 위 메서드들 중
동일한 값 타입 메서드가 선택되어 실행되는 것이다.
앞서 정리한 조건과 관련하여
오버로딩으로 간주하는 경우와 아닌 경우를
예시를 통해 살펴보자면
// ※ 오버로딩 X
/*
- 차이 = 매개변수 "이름"
- 개수 & 타입 : "동일"
*/
int add(int a, int b) { return a + b; }
int add(int x, int y) { return x + y; }
/*
- 차이 = "반환(return) 타입 & 이름"
- 개수 & 타입 : "동일"
*/
int add(int a, int b) { return a + b; }
long add(int x, int y) { return x + y; }
// ※ 오버로딩 O
/*
- 차이 = "매개변수 타입" & return타입
- 개수 : "동일"
*/
int add(int a, int b) { return a + b; }
long add(long a, long b) { return a + b; }
long add(int a, long b) { return a + b; }
long add(long a, int b) { return a + b; }
overriding
)" 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것 "
▶ overriding : "덮어쓰다"의 의미로 하위 클래스에서 덮어쓰는 '재정의'해서 사용하는
위에서 [상위 클래스 / 하위 클래스]라고 구분 지었지만
가장 흔한 표현이고 다들 알 만한 구분은
부모 클래스 / 자식 클래스 인데
이 경우로 다시 설명해보자면
"부모클래스에서 정의한 메서드"를
자식 클래스가 상속받아
부모 클래스에 있던 메서드를 재정의해서 사용하는 것을 말한다.
class Point {
int x ;
int y ;
String getLoc() {
return "x : " + x + ", y : " + y ;
}
}
// 위 Point 클래스를 상속받았을 때
class Point3D extends Point { // 상속관계
// int x ; 부모클래스 멤버 그냥 사용 가능
// int y ; 부모클래스 멤버 그냥 사용 가능
int z ; // Point3D 클래스에서 선언
// 부모클래스에서 이미 상속받았던 getLoc()메서드를 다시 재정의
String getLoc() { // 오버라이딩(overriding)
return "x : " + x + ", y : " + y + ", z : " + z;
}
}
여기서 상속을 받아왔기 때문에
부모클래스에 있던 변수들은
" 자식 클래스 내에서 선언하지 않더라도 "
그대로 사용 가능하다
※ 오버라이딩 조건
메서드 내용만 새로 작성하는 것이기 때문에
메서드의 선언부(이름, 매개변수, 반환타입 )는 완전히 일치해야 한다.❗ 단, 접근제어자(access modifier) & 예외(Exception) 의 경우는 "제한된 조건하"에서 다르게 변경할 수 있다.
1. 접근제어자는 " 조상 클래스의 메서드 "보다 좁은 범위로 변경할 수 없다.
2. " 조상 클래스 "보다 많은 예외 선언은 불가하다.
" 확장 " vs " 재정의 "
오버로딩은
이름이 같은거지
실행에 필요한 매개변수나 타입 등이 서로 다른
즉, 겉은 같고 속은 서로 다른 동명이인 허용하는 형태이고
오버라이딩은
" 부모님 가게를 물려받았지만
자식의 새로운 경영으로 새로운 메뉴를 판매하게 된 가게 "와
비슷한 형태라고 보면
이해가 쉽다.
구분 | 오버로딩 | 오버라이딩 |
---|---|---|
메서드 이름 | 동일 | 동일 |
매개변수 & 타입 | 다름 | 동일 |
Return(반환값) 타입 | 상관 X | 동일 |