절차 지향 프로그래밍과 객체 지향 프로그래밍
클래스 개념이 등장하기 전 C 언어 같은 언어에는 클래스가 없었습니다. C 언어처럼 클래스와 객체가 없는 방식의 프로그래밍을 절차 지향 프로그래밍이라고 부릅니다.
절차 지향 프로그래밍: 프로그램은 일련의 명령 시퀀스이며 실행 단계 최적화가 핵심입니다.
클래스를 사용할 수 있게 되면서 객체 지향 프로그래밍을 구현할 수 있습니다.
객체 지향 프로그래밍: 프로그램은 캡슐화된 여러 클래스로 구성됩니다. 핵심 원리는 데이터 + 데이터를 조작하는 함수를 논리적으로 연관된 단위로 묶는 것이며, 이 단위가 바로 클래스(class)입니다.
클래스의 정의
클래스는 저장할 데이터, 실행 가능한 코드를 포함하는 자료 구조이며 두 가지 종류의 멤버를 담고 있습니다.
- 데이터 멤버(Data Members): 객체 속성 데이터를 저장합니다. 필드(Fields), 상수(Constants)
- 함수 멤버(Function Members): 객체 행위 로직을 수행합니다. 메서드, 속성, 생성자, 소멸자, 연산자, 인덱서, 이벤트 등
클래스는 논리적으로 연관된 데이터와 함수를 캡슐화한 집합으로 현실 세계나 추상 세계의 대상을 표현하기 위해 활용합니다.
한 마디로 정리하면 클래스는 데이터와 함수로 구성된 자료 구조입니다. 클래스로부터 객체를 생성하고 객체를 통해 데이터와 멤버에 접근할 수 있으며 클래스 내부에서도 직접 접근 가능합니다.
클래스 선언
class 키워드는 오직 클래스 템플릿만 정의할 뿐 객체 인스턴스를 생성하지 않습니다. 템플릿은 클래스 이름, 클래스 멤버, 클래스 특징 세 부분으로 구성됩니다.
문법
class 클래스이름
{
// 멤버 선언 (필드, 메서드 등 순서에 제약 없음)
}Code language: JavaScript (javascript)
클래스 선언은 흔히 클래스 정의(class definition)라고도 불립니다.
class Program
{
static void Main(string[] args)
{
AddCalculator addCalculator = new AddCalculator();
SubCalculator subCalculator = new SubCalculator();
}
}
class AddCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Add()
{
return A + B;
}
}
class SubCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Subtract()
{
return A - B;
}
}Code language: JavaScript (javascript)
위 예시에서는 클래스 두 개를 선언했습니다. 하나는 덧셈 연산, 다른 하나는 뺄셈 연산을 처리하며 메인 프로그램 Main 함수 안에서 인스턴스를 생성해 사용합니다.
본 콘텐츠는 foxdevelop.com 출처
클래스 선언을 꼭 위에서 아래 순서로 작성할 필요는 없습니다. 클래스를 아래쪽에 적고 위쪽 메인 함수에서 호출하는 것도 전혀 문제 없습니다. 클래스는 단순한 템플릿 설계도일 뿐 코드가 위에서 아래로 순차 실행되지 않기 때문입니다. 실행은 Main 함수에서 시작하며 해당 클래스가 필요할 때 설계도를 찾아 사용하는 방식입니다.

클래스 멤버
필드(Fields)
필드는 클래스에 소속된 변수입니다. 내장 타입 또는 사용자 정의 타입을 사용할 수 있으며 데이터 읽기와 쓰기를 지원합니다.
타입 필드이름;
class MyClass
{
int MyField; // int 타입 필드 MyField
}Code language: JavaScript (javascript)
C/C++와의 중요한 차이점: C#에는 전역 변수가 존재하지 않습니다. 모든 필드는 반드시 타입(클래스 / 구조체) 내부에 선언해야 합니다.
필드 초기화 규칙
(1) 암시적 초기화 (값을 할당하지 않은 경우)
컴파일러가 자동으로 해당 타입의 기본값을 할당하며 타입마다 기본값은 다릅니다.
int F1; // 기본값 0
string F2; // 기본값 nullCode language: JavaScript (javascript)
아래 표는 C# 타입과 필드 기본값 매칭 목록입니다. 이 규칙은 필드에 적용되며 지역 변수는 개발자가 직접 초기화해야 합니다.
기본 값 타입
| 데이터 타입 | 기본값 | 설명 |
|---|---|---|
sbyte | 0 | 부호 있는 8비트 정수 |
byte | 0 | 부호 없는 8비트 정수 |
short | 0 | 부호 있는 16비트 정수 |
ushort | 0 | 부호 없는 16비트 정수 |
int | 0 | 부호 있는 32비트 정수 |
uint | 0 | 부호 없는 32비트 정수 |
long | 0L | 부호 있는 64비트 정수 |
ulong | 0UL | 부호 없는 64비트 정수 |
float | 0.0f | 단정밀도 부동 소수점 |
double | 0.0d | 배정밀도 부동 소수점 |
decimal | 0.0m | 고정밀도 십진 소수 |
char | '\0' (널 문자, ASCII 0) | 단일 문자 |
bool | false | 불리언 타입 |
열거형 Enum | 기본 정수 0에 해당하는 열거 요소 | 열거형은 정수를 기반으로 하며 기본값은 0 |
구조체 struct | 모든 필드가 각자의 기본값을 가짐 | 사용자 정의 값 타입, 전체 영점 초기화 |
참조 타입
모든 참조 타입의 기본값은 통일적으로 null이며 힙에 존재하는 어떤 객체도 가리키지 않음을 의미합니다.
즉 유효한 메모리 주소를 저장하지 않은 상태입니다. 앞서 살펴본 메모리 도표를 기억하세요. 참조 타입에는 힙 메모리 주소인 000001 01010 같은 값이 저장되는데 null일 경우 아무 메모리 주소도 보관하지 않습니다.
| 타입 분류 | 예시 타입 | 기본값 |
|---|---|---|
| 내장 참조 타입 | string、object | null |
사용자 정의 클래스 class | Person Student | null |
| 배열(모든 차원) | int[]、string[,] | null |
| 대리자 / 이벤트 | Action、Func、사용자 정의 delegate | null |
인터페이스 interface | 모든 인터페이스 변수 | null |
예시
string str; // 기본 null
Student jason; // 사용자 정의 클래스, 기본 null
int[] arr; // 배열, 기본 null
Action callback; // 대리자, 기본 nullCode language: JavaScript (javascript)
널 허용 타입(Nullable / T?)
기본 자료형 뒤에 물음표 ?를 붙이면 다른 타입으로 변환되어 빈 값을 허용합니다. 앞서 설명한 int age; 는 값을 할당하지 않으면 기본값이 0이지만 “값 자체가 없음”을 표현하고 싶다면 int? age2; 와 작성합니다. age2는 널 허용 타입이므로 int? age2 = null;처럼 null을 대입할 수 있습니다.
널 허용 타입은 래핑된 ValueType이며 기본값은 null로 “유효한 값 없음”을 나타냅니다.
| 선언 문법 | 기본값 |
|---|---|
int? num | null |
bool? flag | null |
decimal? price | null |
class Test
{
int a; // 자동으로 0
string b; // 자동으로 null
bool c; // 자동으로 false
}Code language: JavaScript (javascript)
(2) 명시적 초기화
선언할 때 =로 값을 할당합니다. 할당하는 값은 컴파일 시점에 확정되어야 하며 무작위 값이나 사용자 입력 데이터를 직접 적을 수 없습니다.
int days = 25;
string word = "foxdevelop";Code language: JavaScript (javascript)
(3) 동일 타입 다중 필드 약식 선언
동일한 타입은 쉼표로 구분해 한 번에 선언할 수 있습니다. 서로 다른 타입을 섞어 쓸 수 없습니다.
int player, blood = 25;
string title, subTitle = "hi welcome to foxdevelop.com";Code language: JavaScript (javascript)
메서드(Methods)
메서드 정의
메서드는 재사용 가능하고 이름이 지정된 실행 가능 코드 블록으로 C++의 멤버 함수에 해당합니다. 호출되면 내부 코드를 실행하고 호출 지점으로 복귀하며 반환값 유무에 따라 두 종류로 나뉩니다.
메서드의 네 가지 요소
- 반환 타입: 반환값이 없을 경우
void작성 - 메서드 이름
- 매개변수 목록: 매개변수가 없어도
()를 생략할 수 없음 - 메서드 본문:
{}로 실행 코드를 감쌈
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
robot.SayHello();
}
}
class Robot
{
public void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
public void SayHello() 앞쪽의 public은 접근 수식자로 이 함수를 클래스 외부에서 (객체이름.함수이름 형식으로) 호출할 수 있게 합니다. public을 적지 않으면 기본적으로 private(비공개)가 되며 클래스 내부에서만 접근 가능합니다. robot 같은 객체 이름으로 외부에서 호출할 수 없습니다.

클래스 변수와 인스턴스 생성
1. 참조 타입 기본 특징
클래스는 참조 타입에 속하며 메모리는 두 영역으로 나뉩니다.
- 스택(Stack): 참조 변수(메모리 주소 포인터)를 저장
- 힙(Heap): 객체의 실제 데이터를 보관
2. 단계별 객체 생성
1 참조 변수만 선언 (스택 메모리만 할당, 힙에 객체 없음)
Robot robot;
// 스택에 참조 공간만 할당되고 값은 미정의 상태, 힙에는 객체가 존재하지 않음
Code language: JavaScript (javascript)

2 new 연산자로 힙 메모리 할당
new 타입이름();Code language: JavaScript (javascript)
- 힙에 메모리를 할당하고 모든 필드에 자동으로 기본값을 초기화
- 힙 객체의 참조 주소를 반환한 뒤 스택 변수에 대입
robot = new Robot();
Code language: JavaScript (javascript)

class Program
{
static void Main(string[] args)
{
Robot robot;
robot = new Robot();
}
}
class Robot
{
void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
3. 선언과 인스턴스화 한 번에 처리
Robot robot = new Robot();Code language: JavaScript (javascript)
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
}
}Code language: JavaScript (javascript)
클래스 정의