백엔드 수업 #07 상속 - 04 메소드 재정의

sookyoung.k·2022년 11월 28일
0

자식 클래스가 사용하기에 적합하지 않은 메소드가 있을 수 있다. 이 경우에는 자식 클래스에서 메소드를 수정해서 사용하면 된다. 이럴 때 사용하는 기능이 바로 오버라이딩(Overriding)!

● 메소드 재정의(@Override)

메소드 오버라이딩: 상속된 메소드의 내용이 자식 클래스에 맞지 않을 경우, 자식 클래스에서 동일한 메소드를 재정의 하는 것을 말한다.

메소드가 오버라이딩 되면 부모 객체의 메소드는 숨겨진다. 따라서 자식 객체에서 메소드를 호출할 때 오버라이딩 된 자식 메소드가 호출된다.

<주의할 점>

  • 부모 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 리스트)를 가져야 한다.
  • 접근 제한을 더 강하게 오버라이딩 할 수 없다.
    (부모가 public이면 자식 메소드가 default나 private로 수정 불가. 반대는 가능!)
  • 새로운 예외(Exception)를 throws할 수 없다. (이건 나중에 배움)
public class Calculator {
	public double areaCircle(double r) {
		System.out.println("Calculator 객체의 areaCircle() 실행");
		return 3.14159 * r * r;
	}
}
public class Computer extends Calculator {
	@Override  
	public double areaCircle(double r) {
		System.out.println("Computer 객체의 areaCircl() 실행");
		return Math.PI * r * r; // 자바 표준 API 
	}
}

public class ComputerExample {

	public static void main(String[] args) {
		int r = 10;
		
		Calculator calc = new Calculator(); // 부모 클래스 객체 생성 
		System.out.println(calc.areaCircle(r));
		
		Computer com = new Computer(); // 자식 클래스 객체 생성 
		System.out.println(com.areaCircle(r)); // 재정의된 메소드를 호출한다. 
	}

}

[출력결과]
Calculator 객체의 areaCircle() 실행
314.159
Computer 객체의 areaCircl() 실행
314.1592653589793

● 부모 메소드 호출(super)

오버라이딩을 하게 되면 부모 클래스의 메소드는 숨겨진다. 하지만 자식 클래스에서 오버라이딩 된 부모 클래스의 메소드를 호출해야 하는 상황이 온다면 super 키워드를 붙여서 호출이 가능하다.

super.부모메소드();
:super은 부모 객체를 참조하고 있기 때문에 부모 메소드에 직접 접근이 가능

public class Airplane{
	// 메소드 
	public void land() {
		System.out.println("착륙");
	}
	public void fly() {
		System.out.println("일반 비행");
	}
	public void takeOff() {
		System.out.println("이륙");
	}
    // 주의: 메소드에 final을 붙이면 그 메소드는 오버라이드 할 수 없다. 
}

public class SupersonicAirplane extends Airplane {
	// 상수(static final) 선언 (자주 사용하는 고정값은 상수 선언을 통해 가독성을 높인다.)
	// static: 전역변수 (공유)
	public static final int NOMAL = 1;
	public static final int SUPERSONIC = 2;
    
    // 상태 필드 선언
    public int flyMode = NORMAL;
    
	@Override
	public void fly() {
		if (flyMode == SUPERSONIC) {
			System.out.println("초음속 비행");
		} else { // nomal일 때는
			// super.메소드명() -> 부모 클래스의 메소드 실행
			super.fly(); // 부모 클래스의 fly() 메소드를 사용하겠다는 선언, 실행 
		}		
	}
}

public class SupersonicAirplaneEx {

	public static void main(String[] args) {
		SupersonicAirplane sa = new SupersonicAirplane();
		sa.takeOff();
		sa.fly(); 
		sa.flyMode = SupersonicAirplane.SUPERSONIC; // SupersonicAirplane클래스의 상수(SUPERSONIC)를 가져와서 상태 필드값 변경 
		sa.fly(); // supersonic으로 바꿔서 출력 결과도 바뀜!!! 
        sa.flyMode = SupersonicAirplane.NORMAL; // NOMAL 상수를 가져와서 다시 상태 필드값 변경 
        sa.fly();
        sa.land();
	}

}

[출력결과]
이륙합니다.
일반비행합니다.
초음속비행합니다.
일반비행합니다.
착륙합니다.

profile
영차영차 😎

0개의 댓글