Java 메서드 오버라이딩과 static 메서드
요약
Java 메서드 오버라이딩(Override)과 정적 메서드(static method)의 차이를 알아봅니다. Parent ref = new Child() 패턴에서 인스턴스 메서드와 static 메서드의 호출 방식을 이해하여 정보처리기사 실기 문제를 풀어봅니다.
오버라이딩 핵심 정리
| 개념 | 설명 | 예시 |
|---|---|---|
| 오버라이딩 | 부모의 메서드를 자식이 재정의 | int x(int i) { return i + 3; } |
| 동적 바인딩 | 실제 객체 타입의 메서드가 호출됨 | ref.x(2) -> Child의 x() 호출 |
| static 메서드 | 참조 변수 타입에 따라 호출됨 | ref.id() -> Parent의 id() 호출 |
| 오버로딩 | 같은 이름, 다른 매개변수의 메서드 | x(int i) vs x(String s) |
메서드 오버라이딩이란?
오버라이딩(Overriding) 은 부모 클래스에서 이미 정의된 메서드를 자식 클래스에서 같은 이름, 같은 매개변수로 다시 정의하는 것입니다.
쉽게 말하면, "부모의 기능을 자식이 자기만의 방식으로 바꾸는 것" 입니다.
위 코드에서 Child 클래스의 x(int i) 메서드는 Parent 클래스의 x(int i) 메서드를 오버라이딩한 것입니다. 메서드 이름(x), 매개변수(int i), 반환 타입(int)이 모두 같습니다.
오버라이딩이 필요한 이유
상속을 사용하면 부모의 메서드를 그대로 물려받습니다. 하지만 자식 클래스에서 다른 동작이 필요할 때가 있습니다. 이때 오버라이딩을 사용합니다. 특히 추상 클래스의 추상 메서드는 자식 클래스에서 반드시 오버라이딩해야 합니다.
동적 바인딩
동적 바인딩(Dynamic Binding) 은 프로그램이 실행될 때(런타임) 실제 객체의 타입을 보고 어떤 메서드를 호출할지 결정하는 것입니다.
Parent ref = new Child() 패턴
이 패턴이 시험에서 가장 중요합니다. 변수의 타입은 Parent이지만, 실제로 담긴 객체는 Child입니다.
이때 인스턴스 메서드(일반 메서드)를 호출하면, 실제 객체 타입(Child) 의 메서드가 실행됩니다. 이것이 동적 바인딩입니다.
변수 타입이 Parent이므로 Parent의 x()가 호출될 것 같지만, 실제 객체가 Child이므로 Child의 x() 가 호출됩니다.

static 메서드
static 메서드(정적 메서드) 는 객체가 아닌 클래스에 소속된 메서드입니다. 메서드 선언에 static 키워드가 붙어 있습니다.
static 메서드는 오버라이딩되지 않습니다
static 메서드는 클래스에 소속되어 있기 때문에 오버라이딩이 적용되지 않습니다. 자식 클래스에서 같은 이름의 static 메서드를 정의해도, 이것은 오버라이딩이 아니라 각 클래스에 독립적으로 존재하는 별개의 메서드입니다.
실제 객체는 Child이지만, id()가 static 메서드이므로 참조 변수 타입(Parent) 에 따라 Parent.id()가 호출됩니다.
인스턴스 메서드 vs static 메서드 비교
이 표가 시험에서 가장 중요한 핵심입니다.
| 구분 | 인스턴스 메서드 | static 메서드 |
|---|---|---|
| 키워드 | static 없음 | static 있음 |
| 소속 | 객체에 소속 | 클래스에 소속 |
| 오버라이딩 | 가능 | 불가능 |
| 호출 기준 | 실제 객체 타입 (동적 바인딩) | 참조 변수 타입 (정적 바인딩) |
| 예시 | ref.x(2) -> Child의 x() | ref.id() -> Parent의 id() |
메서드 오버로딩
오버로딩(Overloading) 은 같은 이름의 메서드를 매개변수의 타입이나 개수를 다르게 하여 여러 개 정의하는 것입니다.
위 코드에서 x(int i)와 x(String s)는 이름은 같지만 매개변수 타입이 다릅니다. Java는 전달하는 인자의 타입에 따라 어떤 메서드를 호출할지 자동으로 결정합니다.
오버라이딩 vs 오버로딩 비교
| 구분 | 오버라이딩 (Overriding) | 오버로딩 (Overloading) |
|---|---|---|
| 의미 | 부모 메서드를 자식이 재정의 | 같은 이름의 메서드를 여러 개 정의 |
| 메서드 이름 | 같음 | 같음 |
| 매개변수 | 같음 | 다름 (타입 또는 개수) |
| 클래스 관계 | 부모-자식 간 | 같은 클래스 내에서도 가능 |
실전 예제: 문제 풀이 과정
25년 2회 기출문제와 동일한 구조로 단계별 풀이를 연습합니다.
1단계: 클래스 구조 파악
| 클래스 | 메서드 | 타입 | 설명 |
|---|---|---|---|
| Parent | x(int i) | 인스턴스 | i + 2 반환 |
| Parent | id() | static | "P" 반환 |
| Child | x(int i) | 인스턴스 | i + 3 반환 (오버라이딩) |
| Child | x(String s) | 인스턴스 | s + "R" 반환 (오버로딩) |
| Child | id() | static | "C" 반환 |
2단계: ref.x(2) 분석
x(int i)는 인스턴스 메서드 -> 실제 객체 타입 기준- 실제 객체가 Child이므로 -> Child의 x(int i) 호출
- 2 + 3 = 5
3단계: ref.id() 분석
id()는 static 메서드 -> 참조 변수 타입 기준- 참조 변수 타입이 Parent이므로 -> Parent의 id() 호출
- "P" 반환
4단계: 최종 결과
실행 순서 추적
| 순서 | 코드 | 메서드 타입 | 호출 기준 | 결과 |
|---|---|---|---|---|
| 1 | ref.x(2) | 인스턴스 | 실제 객체 (Child) | 5 |
| 2 | ref.id() | static | 참조 변수 (Parent) | "P" |
| 3 | 5 + "P" | - | - | "5P" |