[Java] 메소드 오버라이딩(method overriding)

2020. 4. 27. 22:32Programming Languages/Java

메소드 오버라이딩

슈퍼 클래스에 선언된 메소드와 같은 이름, 같은 리턴 타입, 같은 매개 변수 리스트를 갖는 메소드를 서브 클래스에서 재작성하는 것으로, 슈퍼 클래스와 서브 클래스의 메소드 사이에서 발생한다. '슈퍼 클래스 덮어쓰기'로 생각하면 이해하기 쉽다. 오버라이딩했을 경우 서브 클래스의 메소드가 우선적으로 실행된다. 이런 처리를 동적 바인딩이라고 부른다. 아래 코드를 보자.

class Shape {
    public void draw() {
        System.out.println("Shape");
    }
}

class Line extends Shape {

    @Override
    public void draw() {
        System.out.println("Line");
    }
}

class Rect extends Shape {

    @Override
    public void draw() {
        System.out.println("Rect");
    }
}

class Circle extends Shape {

    @Override
    public void draw() {
        System.out.println("Circle");
    }
}

public class OverridingExample {
    public static void main(String[] args) {
        Shape shape = new Line(); // 업캐스팅
        shape.draw(); // 메소드 오버라이딩
    }
}

이 코드의 출력은 Line 으로 나온다. Shape 타입의 레퍼런스 변수 shape는 Line으로 업캐스팅됐다. 그리고 draw()가 호출됐다. 그렇다면 shape의 draw()로 가는 것이 아닌 Line의 draw()를 찾아가 구문을 실행한다. 이것이 메소드 오버라이딩이다. 이는 곧 다형성과 밀접한 관련이 있다. 한 메소드 형태로 다양한 동작을 하는 것은 객체지향 원칙의 다형성을 이루는 것이다.

오버라이딩하는 메서드에 @Override 어노테이션을 적용하면 컴파일 시에 오버라이딩이 제대로 되었는지 확인할 수 있기 때문에 오버라이딩을 하는 경우에는 반드시 @Override를 적용하도록 하자.

오버라이딩의 조건

  • 슈퍼 클래스의 메소드와 동일한 원형으로 작성한다.
    • 슈퍼 클래스의 메소드와 동일한 이름, 매개변수 타입과 개수, 리턴타입을 갖는 메소드로 작성해야 한다. 하나라도 다른 경우 컴파일 오류가 발생한다.
  • 슈퍼 클래스 메소드의 접근 지정자보다 접근의 범위를 좁혀 오버라이딩할 수 없다.
    • 접근 지정자는 public, protected, default, private 순으로 접근의 범위가 좁아진다. 슈퍼 클래스에서 protected로 선언된 메소드는 서브 클래스에서 protected나 public으로만 오버라이딩할 수 있고, public으로 선언된 메소드는 public으로만 오버라이딩할 수 있다.
  • static이나 private 혹은 final로 선언된 메소드는 서브 클래스에서 오버라이딩할 수 없다.

동적 바인딩(dynamic binding)

실행할 메소드를 컴파일 시에 결정하지 않고 실행 시에 결정하는 것을 말한다. 자바에서는 동적 바인딩을 통해 오버라이딩된 메소드가 항상 실행되도록 보장한다.

super 키워드

그렇다면 만약 메소드가 오버라이딩되어 있는 경우, 슈퍼 클래스의 메소드는 더 이상 쓸 수 없는 것인가? 아니다. super 키워드를 이용하면 슈퍼 클래스의 멤버에 접근할 수 있다. super.draw()로 사용할 수 있다.

super는 자바 컴파일러에 의해 지원되는 것으로 슈퍼 클래스에 대한 레퍼런스이다. super를 이용하면 슈퍼 클래스의 필드와 메소드에 모두 접근할 수 있다.

this, this(), super, super() 정리

  • this - 현재 객체의 모든 멤버
  • super - 현재 객체 내에 있는 슈퍼 클래스 멤버
  • this() - 생성자에서 다른 생성자를 호출할 때 사용
  • super() - 서브 클래스의 생성자에서 슈퍼 클래스의 생성자를 호출할 때 사용

메소드 오버로딩 vs 메소드 오버라이딩

비교 요소 메소드 오버로딩 메소드 오버라이딩
선언 같은 클래스나 상속 관계에서 동일한 이름의 메소드 중복 작성 서브 클래스에서 슈퍼 클래스에 있는 메소드와 동일한 이름의 메소드 재작성
관계 같은 클래스 내 또는 상속 관계 상속 관계
목적 이름이 같은 여러 개의 메소드를 중복 작성하여 사용의 편리성 향상. 다형성 실현 슈퍼 클래스에 구현된 메소드를 무시하고 서브 클래스에서 새로운 기능의 메소드를 재정의하고자 함. 다형성 실현
조건 메소드 이름은 반드시 동일하고, 매개변수 타입이나 개수가 달라야 성립 메소드의 이름, 매개변수 타입과 개수, 리턴 타입이 모두 동일하여야 성립
바인딩 정적 바인딩. 호출될 메소드는 컴파일 시에 결정 동적 바인딩. 런타임에 오버라이딩 메소드를 찾아 호출

 

'Programming Languages > Java' 카테고리의 다른 글

[Java] Thread  (0) 2021.10.19
[Java] 추상 클래스  (0) 2020.05.01
[Java] 업캐스팅, 다운캐스팅, instanceof  (0) 2020.04.27
[Java] 상속과 생성자  (0) 2020.04.21
[Java] 상속과 접근 지정자  (0) 2020.04.21