[TIL] Day 11 — Java 클래스 구조 심화 + 다형성 개념
날짜: 2025-11-03
기술 스택: Java OOP 다형성 접근제어자 상속
부트캠프: 풀스택 개발자 부트캠프 3주차
클래스 구성 요소 총정리
| 구성 요소 |
역할 |
| 멤버변수(필드) |
객체 상태 저장 |
| 메서드 |
객체 동작 정의 |
| 생성자 |
객체 생성 시 초기화 |
| getter/setter |
private 필드 간접 접근 |
| 접근제어자 |
가시성(접근 범위) 제어 |
static 변수 vs 인스턴스 변수
class Counter {
static int total = 0; // 모든 인스턴스 공유 (클래스 레벨)
int count = 0; // 각 객체마다 별도 (인스턴스 레벨)
Counter() { total++; } // 생성될 때마다 total 증가
}
Counter c1 = new Counter();
Counter c2 = new Counter();
System.out.println(Counter.total); // 2 — 공유됨
System.out.println(c1.count); // 0 — 각자 독립
접근제어자 가시성 정리
| 제어자 |
같은 클래스 |
같은 패키지 |
자식 클래스 |
외부 |
private |
✅ |
❌ |
❌ |
❌ |
default |
✅ |
✅ |
❌ |
❌ |
protected |
✅ |
✅ |
✅ |
❌ |
public |
✅ |
✅ |
✅ |
✅ |
- 클래스 선언 앞에는
public 또는 default만 가능
- 메서드에는 4가지 모두 사용 가능
final 키워드
final int MAX = 100; // 변수: 재할당 불가 (상수)
final void display() { /* 구현 */ } // 메서드: 자식 오버라이드 불가
final class Utility { /* 구현 */ } // 클래스: 상속 불가
다형성 (Polymorphism)
class Animal {
void sound() { System.out.println("소리"); }
}
class Dog extends Animal {
@Override
void sound() { System.out.println("멍멍"); }
void fetch() { System.out.println("공 가져오기"); }
}
// 업캐스팅: 부모 타입으로 자식 객체 참조
Animal a = new Dog(); // 업캐스팅 (자동)
a.sound(); // 멍멍 — 오버라이딩된 자식 메서드 호출 (동적 바인딩)
// a.fetch(); // 컴파일 오류 — 부모 타입에 없는 메서드
// 다운캐스팅: 부모 타입 → 자식 타입
Dog d = (Dog) a; // 명시적 다운캐스팅
d.fetch(); // 정상 호출
| 구분 |
설명 |
| 업캐스팅 |
자식 → 부모 타입, 자동 변환 |
| 다운캐스팅 |
부모 → 자식 타입, 명시적 캐스팅 필요 |
| 동적 바인딩 |
런타임에 실제 객체 타입의 메서드 호출 |
트러블슈팅
다운캐스팅 시 ClassCastException
- 원인: 실제 객체 타입이 캐스팅 대상과 다를 때
- 해결:
instanceof로 확인 후 캐스팅
if (a instanceof Dog) {
Dog d = (Dog) a;
d.fetch();
}
default 생성자 관련 오류
- 매개변수 있는 생성자를 정의하면 기본 생성자가 자동 생성되지 않음
new ClassName() 호출 시 오류 → 명시적으로 기본 생성자 추가
더 알아볼 것