티스토리 뷰
주의 사항!
- 이 글은 제가 직접 공부하는 중에 작성되고 있습니다.
- 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
- 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.
부모 클래스의 모든 메서드가 자식 클래스에 맞게 설계되어 있다면 가장 이상적인 상속이지만, 어떤 메서드는 자식 클래스가 사용하기에 적합하지 않을 수도 있습니다. 이 경우 상속된 일부 메서드는 자식 클래스에서 다시 수정해서 사용해야 합니다. 자바는 이런 경우를 위해 메서드 오버 라이딩(Overriding) 기능을 제공합니다.
메서드 재정의(@Override)
메서드가 오버 라이딩되면 부모 객체의 메서드는 숨겨지기 때문에, 자식 객체에서 메서드를 호출하면 오버 라이딩된 자식 메서드가 호출됩니다. 메서드를 오버 라이딩할 때는 다음과 같은 규칙에 주의해서 작성해야 합니다.
- 부모의 메서드와 동일한 시그니처(리턴 타입, 메서드 이름, 매개 변수 리스트)를 가져야 합니다.
- 접근 제한을 더 강하게 오버 라이딩할 수 없습니다.
- 새로운 예외(Exception)를 throws 할 수 없습니다.
접근 제한을 더 강하게 오버 라이딩할 수 없다는 것은 부모 메서드가 public 접근 제한을 가지고 있을 경우 오버 라이딩하는 자식 메서드는 default나 private 접근 제한으로 수정할 수 없다는 뜻입니다. 하지만 그 반대는 가능합니다.
다음 예제는 Calculator의 자식 클래스인 Computer에서 원의 넓이를 구하는 Calcullator의 areaCircle() 메서드를 사용하지 않고, 좀 더 정확한 원의 넓이를 구하도록 오버 라이딩했습니다.
//Calculator.java
package chapter00.exam00;
public class Calculator
{
double areaCircle(double r)
{
System.out.println("Calculator 객체의 areaCircle() 실행");
return 3.14159 * r * r;
}
}
//Computer.java
package chapter00.exam00;
public class Computer extends Calculator
{
@Override
double areaCircle(double r)
{
System.out.println("Computer 객체의 areaCircle() 실행");
return Math.PI * r * r;
}
}
Calculator areaCircle() 메서드는 파이의 값을 3.14159로 계산하였지만, 좀 더 정밀한 계산을 위해 Computer의 areaCircle() 메서드는 Math.PI 상수를 이용합니다. Math는 수학 계산과 관련된 필드와 메서드들을 가지고 있는 클래스로, 자바 표준 API를 제공합니다.
@Override 어노테이션은 생략해도 좋으나, 이것을 붙여주게 되면 areaCircle() 메서드가 정확히 오버 라이딩된 것인지 컴파일러가 체크하기 때문에 개발자의 실수를 줄여주게 됩니다.
//exam00.java
package chapter00.exam00;
public class exam00
{
public static void main(String[] args)
{
int r = 10;
Calculator calculator = new Calculator();
System.out.println("원 면적 : " + calculator.areaCircle(r));
System.out.println();
Computer computer = new Computer();
System.out.println("원 면적 : " + computer.areaCircle(r));
}
}
/*
실행결과
Calculator 객체의 areaCircle() 실행
원 면적 : 314.159
Computer 객체의 areaCircle() 실행
원 면적 : 314.1592653589793
*/
부모 메서드 호출(super)
자식 클래스에서 부모 클래스의 메서드를 오버 라이딩하게 되며, 부모 클래스의 메서드는 숨겨지고 오버 라이딩된 자식 메서드만 사용됩니다. 그러나 자식 클래스 내부에서 오버 라이딩된 부모 클래스의 메서드를 호출해야 하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메서드를 호출할 수 있습니다.
super.부모메서드();
다음 예제는 Airplane 클래스를 상속해서 SupersonicAirplane 클래스를 만들었습니다. Airplane의 fly() 메서드는 일반 비행이지만 SupersonicAirplane의 fly()는 초음속 비행 모드와 일반 비행 모드 두 가지로 동작하도록 설계했습니다.
//Airplane.java
package chapter00.exam00;
public class Airplane
{
public void land()
{
System.out.println("착륙합니다.");
}
public void fly()
{
System.out.println("일반 비행합니다.");
}
public void takeOff()
{
System.out.println("이륙합니다.");
}
}
//SupersonicAirplane.java
package chapter00.exam00;
public class SupersonicAirplane extends Airplane
{
public static final int NORMAL = 1;
public static final int SUPERSONIC = 2;
public int flyMode = NORMAL;
@Override
public void fly()
{
if(flyMode == SUPERSONIC)
{
System.out.println("초음속 비행합니다.");
}
else
{
//Airplane 객체의 fly() 메서드 호출
super.fly();
}
}
}
//exam00.java
package chapter00.exam00;
public class exam00
{
public static void main(String[] args)
{
SupersonicAirplane sa = new SupersonicAirplane();
sa.takeOff();
sa.fly();
sa.flyMode = SupersonicAirplane.SUPERSONIC;
sa.fly();
sa.flyMode = SupersonicAirplane.NORMAL;
sa.fly();
sa.land();
}
}
/*
실행결과
이륙합니다.
일반 비행합니다.
초음속 비행합니다.
일반 비행합니다.
착륙합니다.
*/
'공부 일지 > JAVA 공부 일지' 카테고리의 다른 글
자바, 객체 타입 변환과 다형성 (0) | 2021.04.08 |
---|---|
자바, final 클래스와 final 메서드 (0) | 2021.04.08 |
자바, 상속 (0) | 2021.04.08 |
자바, 어노테이션(Annotation) (0) | 2021.04.07 |
자바, Getter와 Setter 메서드 (0) | 2021.04.07 |