목차
- Hiding이란 무엇인가
- 오버라이딩 vs Hiding 핵심 차이
- static 메서드 Hiding
- 변수 Hiding
- 실전 예제와 함정
1. Hiding이란 무엇인가?
핵심 개념
Hiding = static 메서드나 변수를 자식 클래스에서 "가리는" 것
오버라이딩과 달리, 실제 객체 타입이 아닌 참조 변수 타입을 따라갑니다.
일반 원칙 vs Hiding
java
// 일반 메서드 (오버라이딩)
Parent p = new Child();
p.normalMethod(); // Child의 메서드 실행 (다형성)
// static 메서드 (Hiding)
Parent p = new Child();
p.staticMethod(); // Parent의 메서드 실행 (Hiding!)
2. 오버라이딩 vs Hiding 핵심 차이
비교표
구분 | 오버라이딩(Overriding) | 하이딩(Hiding) |
대상 | 인스턴스 메서드 | static 메서드/변수 |
실행 기준 | 실제 객체 타입 | 참조 변수 타입 |
다형성 | 적용 O | 적용 X |
런타임 결정 | Yes (동적 바인딩) | No (컴파일 타임) |
시각적 이해
[오버라이딩 - 인스턴스 메서드]
Parent p = new Child();
p.method() → "실제 객체가 뭐지?" → Child → Child.method() 실행
[Hiding - static 메서드]
Parent p = new Child();
p.staticMethod() → "변수 타입이 뭐지?" → Parent → Parent.staticMethod() 실행
3. static 메서드 Hiding
기본 예제
java
class P {
public static void print() {
System.out.print("Parent");
}
}
class C extends P {
public static void print() { // Hiding 발생!
System.out.print("Child");
}
}
public class Main {
public static void main(String[] args) {
P myFam = new C();
myFam.print(); // "Parent" 출력!
// 비교: 직접 호출
P.print(); // "Parent"
C.print(); // "Child"
}
}
왜 Parent가 출력되나?
myFam의 타입 체크
↓
P 타입이네?
↓
P의 static print() 호출
↓
"Parent" 출력
※ new C()는 무시됨!
4. 변수 Hiding
멤버 변수도 Hiding 됩니다
java
class Parent {
public String name = "Parent";
public static String type = "ParentType";
}
class Child extends Parent {
public String name = "Child"; // 인스턴스 변수 Hiding
public static String type = "ChildType"; // static 변수 Hiding
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
Child c = new Child();
// 인스턴스 변수
System.out.println(p.name); // "Parent" (변수 타입 따라감)
System.out.println(c.name); // "Child"
// static 변수
System.out.println(p.type); // "ParentType"
System.out.println(c.type); // "ChildType"
}
}
변수 접근 규칙
변수는 항상 참조 타입을 따라갑니다 (메서드와 다름!)
5. 실전 예제와 함정
실무 예제: 로깅 시스템
java
class BaseLogger {
protected String logLevel = "INFO";
public static void configure() {
System.out.println("기본 로거 설정");
}
public void log(String msg) {
System.out.println("[" + logLevel + "] " + msg);
}
}
class CustomLogger extends BaseLogger {
protected String logLevel = "DEBUG"; // 변수 Hiding
public static void configure() { // static 메서드 Hiding
System.out.println("커스텀 로거 설정");
}
@Override
public void log(String msg) { // 일반 메서드 오버라이딩
System.out.println("[커스텀-" + logLevel + "] " + msg);
}
}
public class LogTest {
public static void main(String[] args) {
BaseLogger logger1 = new CustomLogger();
CustomLogger logger2 = new CustomLogger();
// static 메서드 (Hiding)
logger1.configure(); // "기본 로거 설정" (타입 따라감)
logger2.configure(); // "커스텀 로거 설정"
// 인스턴스 메서드 (오버라이딩)
logger1.log("테스트"); // "[커스텀-DEBUG] 테스트" (실제 객체)
logger2.log("테스트"); // "[커스텀-DEBUG] 테스트"
// 변수 접근 (Hiding)
System.out.println(logger1.logLevel); // "INFO" (타입 따라감)
System.out.println(logger2.logLevel); // "DEBUG"
}
}
자주 하는 실수
java
class Animal {
public static void makeSound() {
System.out.println("동물 소리");
}
}
class Dog extends Animal {
public static void makeSound() {
System.out.println("멍멍");
}
}
// 잘못된 다형성 기대
Animal[] animals = {new Dog(), new Cat()};
for(Animal a : animals) {
a.makeSound(); // 모두 "동물 소리" 출력! (의도와 다름)
}
// 해결: static 대신 인스턴스 메서드 사용
정리 : ) 업캐스팅 시 동작 규칙
java
Parent p = new Child();
요소 | 실행되는 것 | 이유 |
생성자 | Parent() → Child() | 부모부터 순서대로 |
인스턴스 메서드 | Child의 메서드 | 오버라이딩 (다형성) |
static 메서드 | Parent의 메서드 | Hiding (타입 따라감) |
인스턴스 변수 | Parent의 변수 | 타입 따라감 |
static 변수 | Parent의 변수 | 타입 따라감 |
암기할 것
오버라이딩 = 실제 객체를 봄 (런타임)
Hiding = 변수 타입을 봄 (컴파일타임)
인스턴스 메서드 → 오버라이딩 → 실제 객체
static 메서드/모든 변수 → Hiding → 참조 타입
⚠️ 실무 권장사항
1. static 메서드는 클래스명으로 호출
java
Parent.staticMethod(); // 권장
p.staticMethod(); // 비권장 (혼란 유발)
2. 다형성이 필요하면 static 사용 금지
java
// Bad
static void process() { }
// Good
void process() { } // 인스턴스 메서드로 변경
3. 변수는 private으로 선언
java
private String name; // Hiding 방지
⚠️ 핵심은 static은 타입을 따라간다는 것!
'Java' 카테고리의 다른 글
Java | 생성자 체인(Constructor Chaining) (0) | 2025.10.11 |
---|---|
Java | 메모리 구조 + static vs 인스턴스 종합 정리 (0) | 2025.10.04 |
Java | 정적 변수 vs 정적 메서드 (2) | 2025.10.04 |
Java | static vs 인스턴스 변수 차이점 (0) | 2025.10.04 |
Java | 업캐스팅과 다운캐스팅 (0) | 2025.10.02 |