오버로딩
한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 메서드 오버로딩, 즉 오버로딩이라고 한다.
오버로딩에는 몇 가지 조건이 있다.
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
메서드의 이름이 같다 하더라도 매개변수가 다르면 서로 구별될 수 있다.
매개변수에 의해서만 구별되므로 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
위의 조건을 만족시키지 못하는 메서드는 중복 정의로 간주되어 컴파일 시 오류가 발생한다.
이제 예시를 통해 알아보겠다.
long add(int a, long b) { return a+b;}
long add(long a, int b) { return a+b;}
두 메서드는 int형과 long형 매개변수가 하나씩 선언되어 있지만, 서로 순서가 다른 경우이다.
이 경우에는 호출 시 매개변수의 값에 의해 호출될 메서드가 구분될 수 있으므로 중복된 메서드 정의가 아닌,
오버로딩으로 간주한다.
이제 한 가지 코드를 더 살펴보겠다.
int add(int a, int 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;
}
위 메서드들은 모두 바르게 오버로딩되어 있다.
정의된 매개변수가 서로 다르긴 해도, 세 메서드 모두 매개변수로 넘겨받은 값을 더해서 그 결과를 돌려준다.
같은 일을 하지만 매개변수를 달리해야 하는 경우에, 이와 같이 이름이 같고 매개변수를 다르게 하여 오버로딩을 한다.
오버라이딩
조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다.
상속받은 메서드를 그대로 사용하기도 하지만, 자손 클래스 자신에 맞게 변경해야 하는 경우가 많다.
이럴 때 조상의 메서드를 오버라이딩한다.
아래와 같이 한 가지 예시를 들어보자.
class Poin{
int x;
int y;
String getLocation(){
return "x : "+ x + ", y : " + y;
}
}
class Point3D extends Point{
int z;
String getLocation(){
return "x : "+ x + ", y : " + y + ", z : " + z;
}
}
2차원 좌표를 출력하는 Point 클래스와 Point클래스를 상속하는 3차원 좌표 클래스 Point3D클래스가 있다.
Point 클래스는 2차원 좌표를 출력하는 getLocation메서드가 있다.
Point3D 클래스는 3차원 좌표를 출력하기 위해 상속 받는 클래스의 메서드인 getLocation을 적절하게 수정했다.
이것이 오버라이딩이다. Point 클래스만 사용하던 사람들은 새로 작성된 Point3D 클래스가 Point 클래스의 자손이므로
getLocation메서드를 사용하면 좌표를 문자열로 얻을 수 있다고 예상할 수 있을 것이다.
오버라이딩에도 몇 가지 조건이 있다.
- 자손 클래스에서 오버라이딩하는 메서드는 조상 클래스의 메서드와
- 이름이 같아야 한다
- 매개변수가 같아야 한다.
- 반환 타입이 같아야 한다.
한마디로 요약하면 선언부가 일치해야 한다는 것이다.
다만 접근제어자와 예외는 제한된 조건 하에서만 다르게 변경할 수 있다.
- 조상 클래스의 메서드를 자손 클래스에서 오버라이딩할 때
- 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- ex 조상 메서드 protected, 오버라이딩한 자손 메서드 private
- 예외는 조상 클래스의 메서드보다 많이 선언할 수 있다.
- 인스턴스 메서드를 static메서드로 또는 그 반대로 변경할 수 없다.
Quiz
조상 클래스에 정의된 static 메서드를 자손 클래스에서 똑같은 이름의 static 메서드로 정의하는 것이 가능한가?
답 : 가능하다. 이건 오버라이딩이 아니고 별개의 메서드를 정의한 것이다.
정리하면
- 오버로딩 : 기존에 없는 새로운 메서드를 정의하는 것
- 오버라이딩 : 상속받은 메서드의 내용을 변경하는 것
참고 자료
자바의 정석
댓글