자바 클래스의 구성 요소: 필드·메소드·생성자 이해하기
자바 클래스의 구성 요소는 객체 지향 프로그래밍(OOP)의 설계도를 이루는 핵심입니다. 이 글에서는 필드(Field), 메소드(Method), 생성자(Constructor) 세 가지를 중심으로 클래스 구조를 상세히 파헤치고, 올바른 설계·사용법까지 안내드립니다.
클래스란 무엇인가?
클래스는 객체를 정의하는 설계도입니다. 자동차(Car) 클래스를 예로 들면, “모델명·연식” 같은 상태(필드)와 “가속·브레이크” 같은 행동(메소드)을 코드로 표현합니다.
클래스의 3대 구성 요소
1. 필드(Field) – 상태(state) 저장소
| 구분 | 설명 | 키워드 |
|---|---|---|
| 클래스 변수 | static 으로 선언, 모든 인스턴스가 공유 |
static int totalCars; |
| 인스턴스 변수 | 객체마다 별도 유지 | String modelName; |
| 지역 변수 | 메소드 내부에서만 유효 | int speed = 100; |
class Car {
static int totalCars; // 클래스 변수
String modelName; // 인스턴스 변수
int modelYear; // 인스턴스 변수
void showDetails() {
int speed = 120; // 지역 변수
System.out.println("속도: " + speed);
}
}
TIP: 필드를 private으로 숨기고 게터/세터로 노출하면 캡슐화가 강화됩니다.
2. 메소드(Method) – 행동(behavior)을 정의
문법
[접근제어자] 반환타입 메소드이름(매개변수...) { ... }
class Car {
void startEngine() { // 반환값 없음
System.out.println("엔진 시작!");
}
int calculateSpeed(int distance,int t){ // 반환값 있음
return distance / t;
}
}
- 메소드 오버로딩으로 같은 이름을 매개변수 다르게 재정의 가능 → 가독성 ↑
3. 생성자(Constructor) – 인스턴스 초기화 담당
특징
- 클래스명과 동일하며 반환 타입 없음
- 기본 생성자는 매개변수 없이 자동 추가(명시 안 하면)
- 오버로딩으로 다양한 초기화 로직 제공
class Car {
String modelName;
int modelYear;
Car() { // 기본 생성자
this("미정", 0);
}
Car(String name, int year) { // 매개변수 생성자
this.modelName = name;
this.modelYear = year;
}
}
인스턴스 생성 과정
Car myCar = new Car("Tesla", 2025);
- new → 힙에
Car객체 생성 - 생성자 호출 → 필드 초기화
- 참조 변수
myCar가 스택에 주소 저장
접근 제어자 한눈에 보기
| 제어자 | 접근 범위 |
|---|---|
public |
모든 클래스 |
| default | 같은 패키지 |
protected |
같은 패키지 + 자식 클래스 |
private |
선언 클래스 내부 |
실전 예제: 클래스 설계 & 사용
public class Car {
private String modelName;
private int modelYear;
private static int totalCars;
Car(String modelName, int modelYear) {
this.modelName = modelName;
this.modelYear = modelYear;
totalCars++;
}
void display() {
System.out.printf("%d년식 %s%n", modelYear, modelName);
}
static int getTotalCars() { return totalCars; }
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Model S", 2023);
Car car2 = new Car("Model 3", 2024);
car1.display(); // 2025년식 Model S
System.out.println("총 차량: " + Car.getTotalCars());
}
}
클래스 구성 최적화 팁
- SRP(단일 책임 원칙): 하나의 클래스는 하나의 기능에 집중
- 불변 객체 필요 시
final필드 + 세터 제거 - 메소드 길이 30줄 이하 유지, 복잡 로직은 분할
- Lombok 등 코드 생성 툴로 보일러플레이트 최소화
질문 정리
-
클래스 변수와 인스턴스 변수 차이는?
클래스 변수는 모든 객체가 공유, 인스턴스 변수는 객체마다 개별 보관합니다.
-
생성자를 여러 개 두면 이점이 있나요?
매개변수 조합별 초기화 로직을 분리해 유연성을 높일 수 있습니다.
-
메소드 오버로딩과 오버라이딩 차이?
오버로딩은 같은 클래스 내 서명 다르게, 오버라이딩은 상위 클래스 메소드를 재정의합니다.
-
게터/세터를 꼭 써야 하나요?
캡슐화를 위해
private필드를 외부에서 안전하게 조작하려면 필요합니다. -
정적 초기화 블록은 언제 사용하나요?
클래스 로딩 시점에 한 번만 실행돼야 하는 복잡 초기화에 적합합니다.
댓글남기기