클래스 정의

절차 지향 프로그래밍과 객체 지향 프로그래밍

클래스 개념이 등장하기 전 C 언어 같은 언어에는 클래스가 없었습니다. C 언어처럼 클래스와 객체가 없는 방식의 프로그래밍을 절차 지향 프로그래밍이라고 부릅니다.

절차 지향 프로그래밍: 프로그램은 일련의 명령 시퀀스이며 실행 단계 최적화가 핵심입니다.

클래스를 사용할 수 있게 되면서 객체 지향 프로그래밍을 구현할 수 있습니다.

객체 지향 프로그래밍: 프로그램은 캡슐화된 여러 클래스로 구성됩니다. 핵심 원리는 데이터 + 데이터를 조작하는 함수를 논리적으로 연관된 단위로 묶는 것이며, 이 단위가 바로 클래스(class)입니다.

클래스의 정의

클래스는 저장할 데이터, 실행 가능한 코드를 포함하는 자료 구조이며 두 가지 종류의 멤버를 담고 있습니다.

  1. 데이터 멤버(Data Members): 객체 속성 데이터를 저장합니다. 필드(Fields), 상수(Constants)
  2. 함수 멤버(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# 타입과 필드 기본값 매칭 목록입니다. 이 규칙은 필드에 적용되며 지역 변수는 개발자가 직접 초기화해야 합니다.

기본 값 타입

데이터 타입기본값설명
sbyte0부호 있는 8비트 정수
byte0부호 없는 8비트 정수
short0부호 있는 16비트 정수
ushort0부호 없는 16비트 정수
int0부호 있는 32비트 정수
uint0부호 없는 32비트 정수
long0L부호 있는 64비트 정수
ulong0UL부호 없는 64비트 정수
float0.0f단정밀도 부동 소수점
double0.0d배정밀도 부동 소수점
decimal0.0m고정밀도 십진 소수
char'\0' (널 문자, ASCII 0)단일 문자
boolfalse불리언 타입
열거형 Enum기본 정수 0에 해당하는 열거 요소열거형은 정수를 기반으로 하며 기본값은 0
구조체 struct모든 필드가 각자의 기본값을 가짐사용자 정의 값 타입, 전체 영점 초기화

참조 타입

모든 참조 타입의 기본값은 통일적으로 null이며 힙에 존재하는 어떤 객체도 가리키지 않음을 의미합니다.

즉 유효한 메모리 주소를 저장하지 않은 상태입니다. 앞서 살펴본 메모리 도표를 기억하세요. 참조 타입에는 힙 메모리 주소인 000001 01010 같은 값이 저장되는데 null일 경우 아무 메모리 주소도 보관하지 않습니다.

타입 분류예시 타입기본값
내장 참조 타입stringobjectnull
사용자 정의 클래스 classPerson Studentnull
배열(모든 차원)int[]string[,]null
대리자 / 이벤트ActionFunc、사용자 정의 delegatenull
인터페이스 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? numnull
bool? flagnull
decimal? pricenull
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++의 멤버 함수에 해당합니다. 호출되면 내부 코드를 실행하고 호출 지점으로 복귀하며 반환값 유무에 따라 두 종류로 나뉩니다.

메서드의 네 가지 요소

  1. 반환 타입: 반환값이 없을 경우 void 작성
  2. 메서드 이름
  3. 매개변수 목록: 매개변수가 없어도 ()를 생략할 수 없음
  4. 메서드 본문: {}로 실행 코드를 감쌈

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. 참조 타입 기본 특징

클래스는 참조 타입에 속하며 메모리는 두 영역으로 나뉩니다.

  1. 스택(Stack): 참조 변수(메모리 주소 포인터)를 저장
  2. 힙(Heap): 객체의 실제 데이터를 보관

2. 단계별 객체 생성

1 참조 변수만 선언 (스택 메모리만 할당, 힙에 객체 없음)
Robot robot; 
// 스택에 참조 공간만 할당되고 값은 미정의 상태, 힙에는 객체가 존재하지 않음
Code language: JavaScript (javascript)
위 코드는 스택 안에 Robot 참조(힙 메모리 주소)를 저장할 변수를 만들지만 현재는 null로 빈 상태입니다.

2 new 연산자로 힙 메모리 할당

new 타입이름();Code language: JavaScript (javascript)
  1. 힙에 메모리를 할당하고 모든 필드에 자동으로 기본값을 초기화
  2. 힙 객체의 참조 주소를 반환한 뒤 스택 변수에 대입
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)

클래스 정의

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다