[Java] 기초 - 클래스, 객체

이지연·2025년 12월 16일

개요

아래의 내용은 java_grammer 레파지토리 C02MethodClass 디렉터리에 저장되어있는 내용을 정리하였다.


클래스의 개요

먼저, 클래스와 객체의 관계를 간단하게 구분하자면 다음과 같다.

  • 클래스(Class) : 객체를 정의하는 틀, 설계도
  • 객체(Instance) : 클래스로부터 만들어진 실제 형태의 데이터

즉, "클래스"는 설계도, "객체"는 완성품이라고 볼 수 있다.
클래스를 정의해두면, 그 클래스를 기반으로 여러 개의 객체(인스턴스)를 만들어 각각의 고유한 데이터 공간을 사용할 수 있다.


클래스의 구성 요소

하나의 클래스는 다음과 같은 요소들로 이루어진다.

  • 필드(Field) : 클래스나 객체 내에서 데이터를 저장하기 위한 변수
  • 메서드(Method) : 동작 또는 기능을 수행하는 코드 블록
    • 클래스 메서드(static O)
    • 객체 메서드(static X)

클래스 메서드의 기본 사용법

아래 예제에서는 Calculator 클래스의 클래스 메서드를 사용했다.

int sum_result = Calculator.sum(10, 20);
System.out.println("Calculator 10 + 20 ===" + sum_result);

Calculator 클래스의 sum() 메서드는 static으로 선언되어 있기 때문에, 객체를 생성하지 않고도
Calculator.sum() 형태로 직접 호출이 가능하다.


클래스 메서드 사용의 문제점

이제 Calculator 클래스의 누적 합(sumAcc) 기능을 예시로 보자.

Calculator.sumAcc(20);
System.out.println("A부서 1월 매출 ===" + Calculator.total); // 20
Calculator.sumAcc(30);
System.out.println("A부서 2월 매출 ===" + Calculator.total); // 40
Calculator.sumAcc(40);
System.out.println("A부서 3월 매출 ===" + Calculator.total); // 90

여기까지는 문제가 없어 보이지만, B부서의 매출을 계산하려 할 때 문제가 생긴다.

Calculator.sumAcc(10);
System.out.println("B부서 1월 매출 ===" + Calculator.total); // 100 (A와 누적됨)
Calculator.sumAcc(30);
System.out.println("B부서 2월 매출 ===" + Calculator.total); // 130 (A+B 누적)

두 부서의 합산 결과가 하나로 합쳐져 버렸다.
그 이유는 Calculator.total 변수가 클래스 변수(static 변수)이기 때문이다.
클래스 변수는 클래스 전체에서 하나의 공간만 공유하기 때문에,
A부서와 B부서가 같은 total을 참조하게 된다.

결국, 클래스 변수와 클래스 메서드만으로는 부서별 고유한 데이터를 관리할 수 없다.


객체를 통한 문제 해결

이 문제를 해결하기 위해 객체를 활용할 수 있다.
클래스를 기반으로 각 부서를 고유 객체로 생성하면 서로 다른 메모리 공간을 사용할 수 있다.

CalculatorForInstance calA = new CalculatorForInstance();
calA.sumAcc(20);
calA.sumAcc(30);
calA.sumAcc(40);
System.out.println("A부서 매출 누적액 ===" + calA.total);
CalculatorForInstance calB = new CalculatorForInstance();
calB.sumAcc(10);
calB.sumAcc(30);
calB.sumAcc(20);
System.out.println("B부서 매출 누적액 ===" + calB.total);

이 경우, calAcalB는 서로 독립적인 힙 메모리 공간을 가진다.
따라서 한 쪽의 total 값이 변경되어도 다른 객체에는 전혀 영향을 주지 않는다.


클래스 메서드 vs 객체 메서드

구분static 키워드호출 방식특징
클래스 메서드있음클래스명.메서드명()객체 상태와 무관하게, 주로 도우미 역할
객체 메서드없음객체명.메서드명()객체 내부 상태(필드)에 접근 및 관리

일반적으로 데이터의 누적, 고유 상태 관리 등이 필요한 경우에는 객체 메서드를 사용하고,
단순 계산이나 유틸리티성 기능에는 클래스 메서드를 사용하는 것이 적절하다.


클래스 메서드 예시

대표적인 클래스 메서드 예시는 Math 클래스에 있다.

System.out.println(Math.min(10, 20));

Math 클래스는 모든 메서드가 static으로 선언되어 있으며,
객체를 생성하지 않고 바로 사용할 수 있다.


객체 메서드 예시

이번에는 ArrayList를 예로 들어보자.

List<Integer> myList = new ArrayList<>();
myList.add(10);
myList.add(20);
System.out.println(myList);

여기서 add()는 객체 메서드다.
myList라는 객체 내에 들어있는 데이터 공간(리스트)에 직접 접근해서 값을 추가한다.
즉, 객체별로 고유의 상태를 가진다.


Calculator vs CalculatorForInstance 코드 비교

클래스 기반 계산기

class Calculator {
    static int total = 0; // 클래스 변수

    public static int sum(int a, int b) {
        return a + b;
    }

    public static int sumAcc(int a) {
        total += a;
        return total;
    }
}
  • static이 붙은 total, sum, sumAcc라는 클래스 변수/메서드는 모두 클래스 단위에서 공유된다.
  • 따라서 하나의 공간에서 모든 객체(또는 호출)가 접근하게 되는 구조이다.

객체 기반 계산기

class CalculatorForInstance {
    int total = 0; // 객체 변수

    static public int sum(int a, int b) {
        return a + b;
    }

    public int sumAcc(int total) {
        this.total += total;
        return this.total;
    }
}
  • total은 객체마다 각각의 힙 영역에 저장된다.
  • this.total을 통해 각 객체 자신을 가리킨다.
  • 부서별, 카테고리별 등 개별 누적 관리가 가능하다.

정리

  • 클래스는 객체를 만들기 위한 설계도이다.
  • static이 붙은 클래스 변수와 메서드는 공용 공간을 사용하기 때문에 상태가 공유된다.
  • 객체를 생성하면 고유한 메모리 공간을 확보해 독립적으로 데이터를 관리할 수 있다.
  • 클래스 메서드는 유틸리티성(독립 계산)에, 객체 메서드는 상태 관리(누적, 변경 등)에 주로 사용한다.
profile
Eazy하게

0개의 댓글