---
title: "클래스는 틀이고 객체는 찍어낸 것이다"
description: "관련 있는 데이터와 그 데이터를 다루는 코드를 한 덩어리로 묶습니다. 틀은 하나지만 찍어낸 것은 여러 개입니다."
author: "유니얼"
pubDate: 2026-09-09
category: "programming/csharp/basics"
tags: ["C#", "기초"]
canonical: https://blog.unialgames.com/posts/csharp-class-and-object/
---
지금까지 데이터는 변수에, 하는 일은 메서드에 따로 두었습니다.
개 두 마리를 다룬다고 해 봅시다.

```csharp
string dog1Name = "바둑";
int dog1Age = 3;

string dog2Name = "초코";
int dog2Age = 5;

void Bark(string name)
{
    Console.WriteLine(name + ": 멍멍");
}
```

돌아가긴 합니다. 문제는 **묶여 있지 않다**는 것입니다.

`dog1Name` 과 `dog1Age` 가 한 마리를 가리킨다는 것은 이름에만 적혀 있습니다.
컴파일러는 모릅니다. `Bark(dog2Name)` 을 넘기든 `Bark("아무거나")` 를 넘기든 똑같습니다.

세 마리가 되면 변수를 여섯 개 만들고, 나이 옆에 몸무게를 추가하려면
`dog1Weight`, `dog2Weight`, `dog3Weight` 를 만듭니다.
그리고 어딘가에서 반드시 `dog1Name` 과 `dog2Age` 를 같이 쓰는 실수가 납니다.

> **관련 있는 데이터와 그 데이터를 다루는 코드를 한 덩어리로 묶는 것이 클래스입니다.**

## 클래스는 이렇게 생겼다

<figure class="diagram">
<svg viewBox="0 0 680 210" role="img" aria-label="클래스 안에 필드와 메서드가 함께 들어 있는 그림">
<g font-family="var(--font-mono)" font-size="16">
<text x="30" y="38" fill="var(--accent)">class</text>
<text x="88" y="38" fill="var(--text)">Dog</text>
<text x="30" y="66" fill="var(--text-muted)">{</text>
<text x="62" y="96" fill="var(--text)">public string Name;</text>
<text x="62" y="122" fill="var(--text)">public int Age;</text>
<text x="62" y="160" fill="var(--text)">public void Bark() { ... }</text>
<text x="30" y="188" fill="var(--text-muted)">}</text>
</g>
<g stroke="var(--border)" stroke-width="1.4" fill="none">
<path d="M300 110 L360 110"></path>
<path d="M300 160 L360 160"></path>
</g>
<g font-size="13" fill="var(--text-muted)">
<text x="372" y="102">가지고 있는 것</text>
<text x="372" y="120">필드</text>
<text x="372" y="156">할 수 있는 것</text>
<text x="372" y="174">메서드</text>
</g>
</svg>
<figcaption>데이터와 기능이 한 상자 안에 있다.</figcaption>
</figure>

```csharp
class Dog
{
    public string Name;
    public int Age;

    public void Bark()
    {
        Console.WriteLine(Name + ": 멍멍");
    }
}
```

클래스 안의 변수를 **필드**라고 합니다. 안의 메서드도 그냥 메서드입니다.
둘을 합쳐 멤버라고 부릅니다.

`Bark` 안에서 `Name` 을 그냥 씁니다. **매개변수로 받지 않습니다.**
같은 상자 안에 있으니 이미 알고 있습니다. 이게 묶는다는 것의 뜻입니다.

`public` 은 밖에서 접근할 수 있다는 표시입니다. 이건 뒤에서 제대로 다룹니다.

## 틀은 하나, 찍어낸 것은 여러 개

붕어빵 틀을 떠올리면 됩니다. **틀 자체는 먹을 수 없습니다.**
틀로 찍어낸 붕어빵을 먹습니다.

```csharp
Dog a = new Dog();
a.Name = "바둑";
a.Age = 3;

Dog b = new Dog();
b.Name = "초코";
b.Age = 5;

a.Bark();       // 바둑: 멍멍
b.Bark();       // 초코: 멍멍
```

`Dog` 는 틀이고, `a` 와 `b` 가 찍어낸 것입니다. 이 찍어낸 것을 **객체**라고 합니다.

`class Dog { ... }` 를 적어 두기만 하면 아무 일도 일어나지 않습니다.
정의를 적어 둔 것이고, 실제로 만드는 것은 `new` 입니다.
메서드에서 정의와 호출을 나눴던 것과 같은 이야기입니다.

> **클래스는 메모리에 없습니다. 객체가 메모리에 있습니다.**

## 객체마다 상태가 따로다

찍어낸 것끼리는 남남입니다.

```csharp
a.Age = 4;
Console.WriteLine(b.Age);    // 5, 그대로입니다
```

`a` 의 `Age` 와 `b` 의 `Age` 는 다른 자리입니다.
필드는 **객체마다 하나씩** 생깁니다.

그래서 이제 실수할 자리가 사라집니다.
`a.Name` 과 `b.Age` 를 섞어 쓰려면 일부러 그렇게 적어야 합니다.
앞의 변수 여섯 개짜리 코드에서는 실수하는 쪽이 더 쉬웠습니다.

`Bark` 는 어떨까요. 메서드는 객체마다 복사되지 않습니다. 코드는 하나입니다.
다만 **누구의 `Bark` 인지**가 다릅니다. `a.Bark()` 로 부르면 `Bark` 안의 `Name` 은 `a` 의 것입니다.

## 마침표는 안으로 들어간다는 뜻이다

`a.Name` 의 마침표는 "그 안의" 라는 뜻입니다.
사실 처음부터 계속 써 왔습니다.

```csharp
text.Length          // 문자열이 가진 것
list.Count           // List 가 가진 것
list.Add(5)          // List 가 할 수 있는 것
Console.WriteLine()  // Console 이 할 수 있는 것
```

`string` 도 `List` 도 클래스입니다. 이제 그 안이 어떻게 생겼는지 짐작이 됩니다.
`Length` 는 필드 비슷한 것이고 `Add` 는 메서드입니다.

우리가 쓰던 것들이 특별한 문법이 아니라 **누군가 만들어 둔 클래스**였습니다.

## 클래스로 묶는 기준

**같이 움직이는 것들**을 묶습니다.

이름과 나이는 개 한 마리에 붙어 다닙니다. 한 마리가 사라지면 둘 다 사라집니다.
그러면 한 상자입니다.

```csharp
class Player
{
    public string Name;
    public int Hp;
    public int Level;

    public void TakeDamage(int amount) { ... }
    public bool IsAlive() { ... }
}
```

`Hp` 를 깎는 코드가 `Player` 밖에 있으면, `Hp` 가 0 아래로 내려가는지
누가 확인할지가 애매해집니다. 안에 두면 `TakeDamage` 한 곳만 보면 됩니다.

**데이터가 있는 곳에 그 데이터를 다루는 코드를 둡니다.** 이게 클래스를 쓰는 이유입니다.

## 정리

- 클래스는 관련 있는 데이터와 기능을 묶는 상자입니다.
- 안의 변수를 필드, 안의 메서드를 그냥 메서드라고 합니다. 합쳐서 멤버입니다.
- 메서드 안에서는 같은 상자의 필드를 매개변수 없이 그대로 씁니다.
- 클래스는 틀이고, `new` 로 찍어낸 것이 객체입니다. 클래스 자체는 메모리에 없습니다.
- 필드는 객체마다 하나씩 생깁니다. 한 객체를 바꿔도 다른 객체는 그대로입니다.
- 마침표는 "그 안의" 라는 뜻입니다. `string` 이나 `List` 도 클래스였습니다.