자바 상속과 관련하여
과거, 김영한님의 자바 강의를 통해 상속의 개념과 다형성, 메서드 오버라이딩에 대해 학습했다. 비슷한 내용으로 글도 올렸었는데, 이번에 정보처리기사 실기를 벼락치기 하는 과정에서 무언가 착각을해도 단단히 착각했다는 것을 깨달았다.
자바에서는 상속 관계에 있는 클래스들 간에 이름이 같은 멤버가 있을 때, 변수 숨김 또는 메서드 오버라이딩이 동작하게 된다. 내가 착각하고 있던 부분은 변수 또한 메서드 오버라이딩처럼 동작할 거란 막연한 생각이었다. 아래 예시를 보자.
public class Main {
public static void main(String[] args) {
Base a = new Derivate();
Derivate b = new Derivate();
System.out.print(a.getX() + a.x + b.getX() + b.x);
}
}
class Base {
int x = 3;
int getX() {
return x * 2;
}
}
class Derivative extends Base {
int x = 7;
int getX() {
return x * 3;
}
}
둘의 차이점은 런타임 시점의 다형성 적용 여부에 있다
1. 메서드 오버라이딩
메서드 오버라이딩이란 부모 클래스에 정의된 메서드를 자식 클래스에서 같은 시그니처(메서드 이름, 파라미터 목록, 반환 타입)로 재정의하는 것이다.
실제로 메서드 오버라이딩은 런타임에 실제 객체의 타입을 따라 결정된다. 즉, 어떤 타입의 참조 변수로 객체를 참조하든, 실제로 생성된 객체의 타입에 해당하는 오버라이딩된 메서드가 호출된다는 말이다. (*다이나믹 메서드 디스패치 또는 런타임 다형성)
2. 변수 숨김
변수 숨김은 같은 이름의 인스턴스 변수(필드)가 정의되어 있을 때 발생한다. 중요한 점은, 이 경우 자식 클래스의 변수가 부모 클래스의 같은 이름인 변수를 숨기게 된다는 점이다.
변수 숨김은 컴파일 타임에 참조 변수의 타입에 따라 결정된다. 즉, 어떤 타입의 참조 변수를 사용하느냐에 따라 접근하는 변수가 달라진다.
숨긴다는 표현이 조금 헷갈릴 수도 있는데, 풀어서 설명하자면 이렇다.
- 자식 클래스에 같은 이름의 변수를 선언한다고 하여, 부모 클래스의 해당 변수가 사라지는 것이 아니다.
- 단지 자식 클래스 스코프 내에서 부모의 변수가 가려지는 것이다. (Hidden의 의미)
이게 도대체 무슨 소리냐면, 자식 클래스 내부에서 x와 같이 변수 이름을 직접 사용하면 자식 클래스의 x가 사용되지만, 부모 타입 참조 변수를 통해 접근하면 부모 클래스의 x가 사용된다는 것이다. (물론, 자식 클래스 내에서 명시적으로 super.x를 사용하면 숨져진 부모 클래스의 x에 접근할 것이다.)
메서드 오버라이딩은 런타임에 결정되고, 변수 숨김은 컴파일 타임에 결정된다.
(한 문장인데 이게 무슨 뜻인지 이해하면 다시는 착각할 일이 없을 듯하다..)
'MAIN > Java & Spring' 카테고리의 다른 글
| 자료구조 힙(Heap), 자바에 TCO가 없는 이유는? (3) | 2025.06.27 |
|---|---|
| JPA 프로젝트에서 타임스탬프 자동화를 위한 세 가지 전략 (1) | 2025.06.10 |
| JPA 스펙에는 컬럼 순서에 대한 명확한 규정이 없다. (1) | 2025.05.28 |
| Spring Boot 드라이버 인식 오류 (driver-class-name) (2) | 2025.05.23 |
| Spring Boot에서 JPA로 Docker MySQL 연동하기 (2) | 2025.05.22 |