오버로딩
오버로딩(Overloading)이란, 한 클래스 내에 이름이 동일한 메서드를 여러 개 작성하는 것이다.
메서드의 이름이 동일해야 한다.
매개변수의 개수나 타입이 달라야 한다.
메서드의 리턴 타입, 접근 지정자는 관계 없다.
EX 1)
class OverloadingExample {
public int getSum(int x, int y) {
return x + y;
}
public int getSum(int x, int y, int z) {
return x + y + z;
}
}
getSum으로 이름이 동일한 메소드 2개가 있다. 이 경우에는 메서드의 이름이 동일하고, 매개 변수의 개수가 2개, 3개로 다르기 때문에 오버로딩이 정상적으로 이루어진다.
EX 2)
class OverloadingExample {
public int getSum(int x, int y) {
return x + y;
}
public double getSum(int x, int y) {
return x + y;
}
}
getSum으로 이름이 동일한 메소드 2개가 있다. 이 경우에는 메서드의 이름이 동일하지만, 매개 변수의 개수와 타입이 동일하기 때문에 컴파일 오류가 발생한다.
오버라이딩
오버라이딩(Overriding)이란, 슈퍼 클래스의 메소드를 서브 클래스에서 재정의하는 것이다.
슈퍼 클래스에 선언된 메소드와 동일한 이름, 리턴 타입, 매개 변수를 갖는 메소드를 가지고
서브 클래스에서 원하는 바를 이루지 못할 때, 재정의하여 사용된다.
슈퍼 클래스에서의 메소드는 무시되고 오버라이딩된 메소드가 무조건 실행된다.
바인딩(Binding), 함수 호출 부분에 함수가 실제 위치한 메모리 주소로 연결해주는 것.
정적 바인딩(Static Binding), 실행할 메소드를 컴파일 시간에 결정한다.
함수는 기본적으로 정적 바인딩된다.
동적 바인딩(Dynamic Binding), 실행할 메소드를 컴파일 시간(compile time)이 아닌, 실행 시간(run time)에 결정한다.
이를 통해 항상 오버라이딩된 메서드가 실행된다.
Super 객체 생성 후, Super의 draw 메소드가 호출된다.
Sub 클래스에서 Super의 draw를 오버라이딩한 상황이다.
슈퍼 클래스와 서브 클래스에 동일한 함수가 들어있으므로, Sub 객체가 생성되고 draw 메서드를 호출하려고 할 때, 동적 바인딩이 일어난다. 동적 바인딩을 통해 항상 오버라이딩된 Sub의 draw 메서드가 호출된다.
동일한 메소드 이름, 매개변수의 타입과 개수, 리턴 타입이어야 한다.
슈퍼 클래스의 접근 지정자보다 좁은 접근 지정자는 사용해선 안된다.
static, private, final로 선언된 메소드는 오버라이딩할 수 없다.
Super
슈퍼 클래스에 접근하고 싶다면 super 키워드를 사용한다.
class Super {
public void draw(){
System.out.println("Super");
}
}
class Sub extends Super {
@Override
public void draw() {
super.draw();
}
}
public class Main {
public static void main(String[] args){
Super sp2 = new Sub();
sp2.draw();
}
}
마무리
오버로딩과 오버라이딩은 다형성(Polymorphism)을 실현하는 방법이다.
둘의 차이를 정리하자면,
@Override 작성 이유
오버라이딩을 할 때, 슈퍼 클래스의 메소드와 동일한 이름, 매개 변수 타입과 개수, 리턴 타입이어야 한다.
이 과정에서 실수로 잘못 정의하게 되는 경우엔, 서브 클래스에서 새로운 메소드를 작성했다고 판단되어 컴파일 오류가 발생하지 않는다.
따라서, @Override라는 annotaion을 오버라이딩하는 메소드 앞에 붙여서, 오버라이딩을 하고 있다는 것을 명시해줌으로써, 컴파일러에게 오버라이딩이 제대로 이루어지고 있는지 확인하도록 한다.