이름은 비슷하지만 의미는 다른 두 개념인 오버로딩(Overloading)과 오버라이딩(Overriding)에 관한 정리이다.
오버로딩을 통해 불필요한 함수 이름의 난발을 막을 수 있다.
예를 들어 숫자 2개와 3개를 더하는 메소드를 살펴보자.
class Calc {
public int sum1(int a, int b){
return a + b;
}
public int sum2(int a, int b, int c){
return a + b + c;
}
public double sum3(double a, double b){
return a + b;
}
}
만약 오버로딩이 지원되지 않았다면 위와 같이 같은 기능을 하는 메소드여도
각기 이름을 달리해서 정의해야했을 것이다.
하지만 오버로딩이 지원되니 다음과 같이 같은 이름의 메소드를 중복해서 정의할 수 있다.
class Calc {
public int sum(int a, int b){
return a + b;
}
public int sum(int a, int b, int c){
return a + b + c;
}
public double sum(double a, double b){
return a + b;
}
}
주의해야 할 점은 오버로딩의 조건이 파라미터의 갯수나 타입이라는 것이다.
리턴 타입의 차이로는 오버로딩이 성립되지 않는다.
class Calc {
public int sum(int a, int b){
return a + b;
}
public double sum(int a, int b){
return (double)a + b;
}
}
이와 관련된 내용을 학부 프로그래밍 언어 강의에서도 접한 적이 있는데 정적 바인딩 과 관련이 있다.
정적 바인딩 :
컴파일 타임에서(실행 시간 전) 호출된 메소드가 결정되는 바인딩으로, 실행 시간에는 변하지 않은 상태로 유지되는 바인딩
컴파일러의 입장에서 매개 변수의 갯수나 타입으로 컴파일 타임(CompileTime)에서 어떤 메소드를 호출할 지 구분할 수 있다.
만약 매개 변수의 갯수나 타입이 완전히 일치하지만 리턴 타입이 다른 경우,
런타임(Runtime)에서만 해당 메소드의 실행 결과 타입을 유추할 수 있다.
정적 바인딩은 실행 중에 동적으로 객체의 타입이 변하는 상황에서는 적용되지 않는다.
선언부가 부모 클래스의 메소드와 동일해야 한다는 것은 다음과 같다.
class Calc {
public int sum(int a, int b){
return a + b;
}
}
class Calc2 extends Calc{
public int sum(int a, int b){
return a + b;
}
}
부모와 자식 클래스의 내용은 완전히 같은 상황이지만
엄연히 자식 클래스에서 sum() 메소드는 재정의 되었다.
그리고 선언부가 일치하므로 오버라이딩에 해당된다.
하지만 아래와 같은 경우는 오버라이딩이 아니다.
class Calc {
public int sum(int a, int b){
return a + b;
}
}
class Calc2 extends Calc{
public int sum(int a, int b, int c){
return a + b;
}
}
내용의 일치 여부와 상관없이 선언부가 일치하지 않으므로 오버라이딩에 해당하지 않는다.