본문 바로가기
java/개념

메소드 오버라이딩(+동적 바인딩)

by unhyepnhj 2024. 5. 22.

메소드 오버라이딩(method overriding): 슈퍼 클래스의 메소드를 서브 클래스에서 재정의

- 슈퍼 클래스에 있는 메소드로 목적하는 바를 이룰 수 없을 때 동일한 메소드를 서브 클래스에 다시 작성

- 슈퍼 클래스 메소드의 이름, 매개변수 타입, 매개변수 개수, 리턴 타입 등 모든 것을 동일하게 작성

- '슈퍼 클래스 메소드 무시하기' 혹은 '덮어쓰기'

- 오버라이딩된 메소드가 무조건 실행되는 동적 바인딩 발생


메소드 오버라이딩 사례

Shape 클래스의 draw() 메소드를 Line, Rect, Circle 클래스에서 각각 오버라이딩

Line line = new Line();
line.draw();

- new Line()에 의해 생성된 객체에는 2개의 draw() 메소드가 존재

- 레퍼런스 line이 Line 타입이므로 컴파일러는 line.draw(); 실행 시 Line 클래스의 draw() 메소드를 호출

Shape shape = new Line();	//업캐스팅
shape.draw();

- new Line()에 의해 생성된 Line 객체에는 2개의 draw() 메소드가 존재

- 레퍼런스 shape이 Shape 타입이므로 shape.draw() 컴파일 시 컴파일러는 Shape 클래스에 draw() 멤버가 있는지 확인한 후 Shape의 draw() 호출

- shape.draw() 실행 시 shape이 가리키는 객체에 Shape의 draw를 오버라이딩한 Line의 draw() 존재

- Line의 draw() 실행

- 위 과정이 동적 바인딩


오버라이딩의 목적: 다형성 실현

- 오버라이딩은 슈퍼 클래스에 선언된 메소드를 각 서브 클래스들이 자신만의 내용으로 새로 구현하는 기능

- 상속을 통해 하나의 객체 지향의 다형성(하나의 인터페이스(=같은 이름)에 서로 다른 내용 구현) 실현

- 실행 시간 다형성 실현


오버라이딩의 제약 사항

 

1. 슈퍼 클래스의 메소드와 동일한 원형으로 작성

- 이름, 매개변수(타입과 개수), 리턴 타입 동일

 

2. 슈퍼 클래스 메소드의 접근 지정자보다 접근 범위를 좁혀 오버라이딩 불가

- 접근 지정자는 public>protected>default>private 순으로 접근 범위가 좁아짐

- 슈퍼 클래스에서 public로 선언된 메소드를 protected로 오버라이딩 할 수 없음

 

3. static이나 private, final로 선언된 메소드를 오버라이딩 할 수 없음


메소드 오버라이딩 활용

- 서브 클래스 개발자가 슈퍼 클래스의 특정 메소드를 새로 만들어 사용하고자 할 때

//예제 5-5 Shape, Line, Rect, Circle 클래스 활용

public class UsingOverride{
	public static void main(String[] args){
    	//링크드 리스트로 도형 생성하여 연결
        start=new Line();	//Line 객체 연결
        last=start;
        obj=new Rect();
        last.next=obj;		//Rect 객체 연결
        last=obj;
        obj=new Line();		//Line 객체 연결
        last.next=obj;
        last=obj;
        obj=new Circle();	//Circle 객체 연결
        last.next=obj;
        //모든 도형 출력
        Shape p=start;
        while(p!=null){
        	p.draw();
            p=p.next;
        }
    }
}

- start 변수는 링크드 리스트의 시작 레퍼런스 저장

- last는 링크드 리스트에 연결된 마지막 도형 객체의 레퍼런스 저장

- obj는 새로 생긴 도형 객체의 레퍼런스 저장

- start에서부터 연결된 모든 도형 객체를 방문하며 draw() 메소드 호출


동적 바인딩: 실행할 메소드를 실행 시(run time)에 결정

- 정적 바인딩: 실행 이전에 값 확정

- 자바에서는 동적 바인딩을 통해 오버라이딩된 메소드가 무조건 실행되게끔 함

 Shape a = new Shape();
 a.paint();		//paint()는 Shape의 draw()를 호출
Shape b = new Cirle();
b.paint();		//paint()는 Circle에서 오버라이딩한 draw() 호출

오버라이딩과 super

- 메소드가 오버라이딩되면 동적 바인딩에 의해 항상 서브 클래스에 오버라이딩한 메소드 호출

- super를 이용해 슈퍼 클래스의 멤버에 접근 가능

- super: 자바 컴파일러에 의해 지원되는 슈퍼 클래스에 대한 레퍼런스

- 컴파일러는 super의 접근을 정적 바인딩으로 처리

- super는 서브 클래스에서만 사용

name = "Circle";	//Circle 클래스의 name에 "Circle" 기록
super.name = "Shape";	//Shape 클래스의 name에 "Shape" 기록
super.draw();		//Shape 클래스의 draw() 호출, 정적 바인딩


 

오버라이딩 vs 오버로딩


예제 5-5 아래 코드의 실행 결과

class Shape{
	public Shape next;
	
	public Shape() {next=null;}
	public void draw() {System.out.println("Shape");}
}
class Line extends Shape{
	public void draw() {System.out.println("Line");}
}
class Rect extends Shape{
	public void draw() {System.out.println("Rect");}
}
class Circle extends Shape{
	public void draw() {System.out.println("Circle");}
}
public class MethodOverridngEx {
	static void paint(Shape p) {
		p.draw();
	}
	public static void main(String[] args) {
		Line line=new Line();
		paint(line);
		paint(new Shape());
		paint(new Line());
		paint(new Rect());
		paint(new Circle());
	}
}

 

예제 5-6 게임에서 대포를 구현하기 위해 Cannon 클래스를 작성

  • 무기를 표현하는 Weapon 클래스를 만들고 살상능력을 리턴하는 fire() 메소드를 작성하면 다음과 같다.
class Weapon{
	protected int fire() {
		return 1;		//무기는 기본적으로 한 명만 공격
	}
}

 

  • Cannon 클래스는 Weapon을 상속
  • Cannon은 10명을 공격하므로 fire() 메소드를 이에 알맞게 오버라이딩
  • main()을 작성하여 테스트

 

'java > 개념' 카테고리의 다른 글

인터페이스(interface)  (0) 2024.05.23
추상 클래스  (0) 2024.05.23
업캐스팅과 다운캐스팅(+instanceof 연산자)  (0) 2024.05.22
상속과 생성자  (0) 2024.05.21
상속과 접근지정자  (0) 2024.05.21