-java 로 예제-
5절 메소드의 오버로딩과 오버라이딩
오버로딩(overloading)과 오버라이딩(overriding)은 하나의 클래스내에 동일한 이름의 클래스가 존재하거나, 혹은 하위 클래스에서 상위클래스에 있는 "같은 이름의" 메소드를 다시 선언하여 사용하는 것으로서 이 두 가지는 메소드명은 같더라도 다음과 같은 차이가 있다.
overloading: 클래스의 이름은 같으나 인자가 다른 경우
overriding: 인자와 리턴타입 모두 같은 경우
5.1 메소드 오버로딩
한 클래스에 동일한 이름의 메소드가 존재하는 경우 서로 오버로딩관계이며, 또한 여러 종류의 생성자가 존재하는 경우에도 모두 서로 overloading 관계이다. 오버로딩이 필요한 이유는 같은 (또는 매우 유사한) 기능을 수행하는 메소드들로서 인자의 타입이 여러 가지 경우가 필요할 때 사용된다. 다음 프로그램은 인자의 종류에 따라서 서로 다른 메소드가 호출되어 2와 1이 출력된다.
class A {
void test(int i) { System.out.println("1"); }
void test(double i) { System.out.println("2"); }
public static void main(String [] args) {
A a = new A();
a.test(1.0);
a.test(1);
}
}
오버로딩된 메소드들은 실제로 서로 무관한 함수처럼 취급된다. 즉 한 메소드 내에서 다른 오버로드된 메소드를 다시 호출할 수도 있으며 이것은 전혀 관계가 없는 메소드를 호출하듯이 호출하면 된다.
참고로 오버로딩된 경우 적합한 메소드를 찾아서 실행하는 순서는 다음과 같다.
메소드의 이름
메소드의 인자의 개수
각 인자들의 데이터 형 (data type)
5.2 메소드 오버라이딩(overriding)
메소드 중복의 주된 목적은 하위클래스에서 상위클래스의 메소드의 동작을 "변경" 시키기 위한 것으로, 오버로딩과 오버라이딩의 주요 차이점은 다음과 같다.
오버로딩된 메소드들은 각각 나름대로 계속 사용이 가능하나, 중복된 메소드의 경우는 나중에 정의한 메소드만 사용할 수 있다.
하나의 클래서 내에서 다수의 오버로딩된 메소드들을 정의할 수 있으나, 중복은 한 하위클래스에서는 "한번만" 정의할 수 있다.
오버로딩 메소드들의 인자는 서로 조금이라도 달라야 하지만 중복된 메소드들은 모든 인자와 리턴 타입도 반드시 일치해야 한다.
오버로딩은 어떤 메소드의 구현내용을 다양하게 즉 다른 형태로 동시에 제공하기 위하여 사용되지만 중복은 메소드의 구현내용을 하위클래스에서 바꾸기 위하여 사용되는 것이다. 메소드 중복은 위와 같은 조건외에도 다음과 같은 조건을 만족하여야 한다.
새로운 메소드의 접근성이 더 좁아지면 안된다. (not more private)
새로운 메소드가 상위클래스의 메소드보다 더 넓은 범위의(상위의) 예외(checked exception)를 발생시키면 안된다. (원래 메소드가 이 예외를 잡을 수 없게 되므로)
주의할 것은 인자는 같고 리턴 타입만 다른 경우는 overloading이 아니며, 컴파일 오류를 발생시킨다. 따라서 같은 클래스 내에서 또는 하위클래스에서 같은 이름과 인자를 같는 메소드는 반드시 같은 리턴 타입을 갖어야 한다.
한편 중복된 (즉 상위클래스에 있는) 메소드를 하위클래스에서 호출할 필요도 있는데 이때는 super.XXX() 와 같이 super를 사용하면 되지만, 두 번 이상 메소드가 중복된 경우에 두 단계 이상 위에 있는 클래스에 있는 (중복) 메소드를 직접 호출할 수는 없다.
주의: 변수와 메소드를 엑세스할 때의 차이점
아래의 코드중 First s = new Second();에서 s가 멤버 변수(s.var)를 엑세스할 때는 s의 타입인 First이 사용되나, s가 메소드(s.method())를 엑세스할 때는 s가 가리키는 객체참조의 실제타입인 Second가 사용된다. 프로그램의 실행결과는 1과 2가 된다.
class First {
int var = 1;
int method() { return var; }
}
class Second extends First {
int var = 2;
int method() { return var; }
}
public class Test {
public static void main(String[] args) {
First s = new Second();
System.out.println(s.var);
System.out.println(s.method());
}
}
-java 예제-