반응형
자바를 공부하다 보면 한 번쯤 궁금해지는 질문입니다. "왜 클래스 본문에 직접 코드를 실행할 수 없을까?" 이 글에서는 자바의 설계 철학을 통해 그 이유를 알아보겠습니다.
잘못된 코드 예시
먼저 다음과 같은 코드는 왜 컴파일 에러가 발생할까요?
class Person {
void cry() {
System.out.println("흑흑");
}
}
class Child extends Person {
protected void cry() {
System.out.println("잉잉");
}
super.cry(); // ❌ 컴파일 에러!
}
또는
class Person {
void cry() {
System.out.println("흑흑");
}
}
class Child extends Person {
protected void cry() {
System.out.println("잉잉");
}
cry(); // ❌ 컴파일 에러!
}
답은 간단합니다. 실행문은 메서드 안에 있어야 하기 때문입니다.
왜 메서드 안에 있어야 할까?
1. 실행 시점의 명확성
메서드는 "언제 실행될지"가 명확합니다:
class Child {
cry(); // ❌ 언제 실행되는 거지? 클래스 로딩할 때? 객체 생성할 때?
void someMethod() {
cry(); // ✅ someMethod()가 호출될 때 실행!
}
}
메서드 밖에 있는 실행문은 언제 실행되어야 하는지 모호합니다. 반면 메서드 안에 있으면 해당 메서드가 호출될 때 실행된다는 것이 명확합니다.
2. 객체 지향의 원칙
객체 지향 프로그래밍에서 객체는 "상태(필드)"와 "행동(메서드)"로 구성됩니다:
class Child {
String name; // 상태 (데이터)
void cry() { // 행동 (동작)
System.out.println("잉잉");
}
cry(); // ❌ 이건 뭐지? 상태도 행동도 아님
}
클래스 본문에 직접 실행문을 쓰는 것은 객체 지향의 기본 구조를 해칩니다.
3. 코드의 예측 가능성
자바는 코드의 흐름을 예측하기 쉽게 만들기 위해 실행 컨텍스트를 명확히 구분합니다. 이렇게 하면:
- 코드를 읽기 쉽고
- 디버깅이 편하며
- 유지보수가 용이합니다
올바른 코드 작성법
실행문을 사용하려면 다음과 같이 메서드 안에 작성해야 합니다:
class Person {
void cry() {
System.out.println("흑흑");
}
}
class Child extends Person {
protected void cry() {
System.out.println("잉잉");
super.cry(); // ✅ 메서드 안에서는 가능!
}
}
또는 별도의 메서드를 만들어서:
class Person {
void cry() {
System.out.println("흑흑");
}
}
class Child extends Person {
protected void cry() {
System.out.println("잉잉");
}
void cryLikeParent() { // ✅ 별도 메서드 안에서
super.cry();
}
}
예외: 실행 코드를 쓸 수 있는 특별한 곳들
사실 메서드 외에도 실행 코드를 작성할 수 있는 몇 가지 예외가 있습니다:
class Child {
// ✅ 필드 초기화
int age = 10;
// ✅ 인스턴스 초기화 블록 (객체 생성 시 실행)
{
System.out.println("객체 생성 시 실행");
cry();
}
// ✅ static 초기화 블록 (클래스 로딩 시 실행)
static {
System.out.println("클래스 로딩 시 실행");
}
// ✅ 생성자
Child() {
System.out.println("생성자 실행");
cry();
}
void cry() {
System.out.println("잉잉");
}
}
이들도 결국은 "언제 실행되는지"가 명확한 실행 컨텍스트입니다:
- 필드 초기화: 객체 생성 시
- 초기화 블록: 객체 생성 시 (생성자 전)
- static 블록: 클래스가 메모리에 로딩될 때
- 생성자: 객체 생성 시
정리
클래스 본문에 직접 쓸 수 있는 것:
- ✅ 필드 선언:
int age = 10; - ✅ 메서드 선언:
void cry() { ... } - ✅ 생성자:
Child() { ... } - ✅ 초기화 블록:
{ ... }
클래스 본문에 직접 쓸 수 없는 것:
- ❌ 실행문:
super.cry();,System.out.println();등
결론: 자바는 "코드가 언제 어떻게 실행될지"를 명확하게 하기 위해, 실행문은 반드시 메서드, 생성자, 초기화 블록 같은 "실행 컨텍스트" 안에 있어야 합니다. 이렇게 하면 코드의 흐름을 예측하기 쉽고 관리하기도 편해집니다.
728x90
반응형
'코딩 > Java' 카테고리의 다른 글
| 추상클래스, 왜 사용할까? (0) | 2026.02.16 |
|---|