클래스 소개

참조 형식

class(으)로 정의된 형식은 참조 형식입니다. 런타임에 참조 형식의 변수를 선언할 때 변수는 new 연산자를 사용하여 클래스의 인스턴스를 명시적으로 만들거나 다음 예제와 같이 다른 곳에서 생성되었을 수 있는 호환되는 형식의 개체를 할당할 때까지 null 값을 포함합니다.

//Declaring an object of type MyClass.
MyClass mc = new MyClass();

//Declaring another object of the same type, assigning it the value of the first object.
MyClass mc2 = mc;

개체가 만들어지면 해당 특정 개체에 대해 관리되는 힙에 충분한 메모리가 할당되고 변수에는 개체 위치에 대한 참조만 포함됩니다. 개체에서 사용하는 메모리는 가비지 수집으로 알려진 CLR의 자동 메모리 관리 기능에 의해 회수됩니다. 가비지 수집에 대한 자세한 내용은 자동 메모리 관리 및 가비지 수집을 참조하세요.

클래스 선언

클래스는 다음 예제와 같이 class 키워드와 뒤에 고유 식별자를 사용하여 선언됩니다.

//[access modifier] - [class] - [identifier]
public class Customer
{
   // Fields, properties, methods and events go here...
}

선택적 액세스 한정자는 class 키워드 앞에 옵니다. 이 경우 public(이)가 사용되므로 누구나 이 클래스의 인스턴스를 만들 수 있습니다. 클래스 이름은 class 키워드 뒤에 옵니다. 클래스의 이름은 유효한 C# 식별자 이름이어야 합니다. 정의의 나머지 부분은 동작과 데이터가 정의되는 클래스 본문입니다. 클래스의 필드, 속성, 메서드 및 이벤트를 모두 클래스 멤버라고 합니다.

개체 만들기

서로 같은 의미로 사용되는 경우도 있지만 클래스와 개체는 서로 다릅니다. 클래스는 개체의 형식을 정의하지만 개체 자체는 아닙니다. 개체는 클래스에 기반을 둔 구체적 엔터티이고 클래스의 인스턴스라고도 합니다.

다음과 같이 new 키워드와 뒤에 클래스 이름을 사용하여 개체를 만들 수 있습니다.

Customer object1 = new Customer();

클래스 인스턴스가 만들어질 때 개체에 대한 참조가 다시 프로그래머에게 전달됩니다. 이전 예제에서 object1Customer에 기반을 둔 개체에 대한 참조입니다. 이 참조는 새 개체를 참조하지만 개체 데이터 자체는 포함하지 않습니다. 실제로 개체를 만들지 않고도 개체 참조를 만들 수 있습니다.

Customer object2;

이러한 참조를 통해 개체에 액세스하려고 하면 런타임에 실패하므로 개체를 참조하지 않는 개체 참조를 만들지 않는 것이 좋습니다. 새 개체를 만들거나 다음과 같은 기존 개체를 할당하여 개체를 참조하도록 참조를 생성할 수 있습니다.

Customer object3 = new Customer();
Customer object4 = object3;

이 코드에서는 같은 개체를 참조하는 두 개의 개체 참조를 만듭니다. 따라서 object3을 통해 이루어진 모든 개체 변경 내용은 이후 object4 사용 시 반영됩니다. 클래스에 기반을 둔 개체는 참조를 통해 참조되므로 클래스를 참조 형식이라고 합니다.

생성자 및 초기화

이전 섹션에서는 클래스 형식을 선언하고 해당 형식의 인스턴스를 만드는 구문을 소개했습니다. 형식의 인스턴스를 만들 때 해당 필드와 속성이 유용한 값으로 초기화되었는지 확인하려고 합니다. 값을 초기화하는 방법에는 여러 가지가 있습니다.

  • 기본값 수용
  • 필드 이니셜라이저
  • 생성자 매개 변수
  • 개체 이니셜라이저

모든 .NET 형식에는 기본값이 있습니다. 일반적으로 이 값은 숫자 형식의 경우 0이고 모든 참조 형식에 대해서는 null입니다. 앱에서 적절한 경우 해당 기본값을 사용할 수 있습니다.

.NET 기본값이 올바른 값이 아닌 경우 필드 이니셜라이저를 사용하여 초기 값을 설정할 수 있습니다.

public class Container
{
    // Initialize capacity field to a default value of 10:
    private int _capacity = 10;
}

호출자가 초기 값을 설정하는 생성자를 정의하여 초기 값을 제공하도록 요구할 수 있습니다.

public class Container
{
    private int _capacity;

    public Container(int capacity) => _capacity = capacity;
}

C# 12부터 클래스 선언의 일부로 기본 생성자를 정의할 수 있습니다.

public class Container(int capacity)
{
    private int _capacity = capacity;
}

클래스 이름에 매개 변수를 추가하면 기본 생성자가 정의됩니다. 이러한 매개 변수는 해당 멤버를 포함하는 클래스 본문에서 사용할 수 있습니다. 이를 사용하여 필드 또는 필요한 다른 곳을 초기화할 수 있습니다.

속성에서 required 한정자를 사용하고 호출자가 개체 이니셜라이저를 사용하여 속성의 초기 값을 설정하도록 허용할 수도 있습니다.

public class Person
{
    public required string LastName { get; set; }
    public required string FirstName { get; set; }
}

required 키워드를 추가하면 호출자가 해당 속성을 new 식의 일부로 설정해야 합니다.

var p1 = new Person(); // Error! Required properties not set
var p2 = new Person() { FirstName = "Grace", LastName = "Hopper" };

클래스 상속

클래스는 개체 지향 프로그래밍의 기본적인 특성인 ‘상속’을 완전히 지원합니다. 클래스를 만들 때 sealed(으)로 정의되지 않은 다른 클래스에서 상속할 수 있습니다. 다른 클래스는 클래스에서 상속하고 클래스 가상 메서드를 재정의할 수 있습니다. 또한 하나 이상의 인터페이스를 구현할 수 있습니다.

상속은 파생을 통해 수행합니다. 즉, 클래스는 데이터와 동작을 상속하는 소스 기본 클래스를 사용하여 선언됩니다. 다음과 같이 파생 클래스 이름 뒤에 콜론 및 기본 클래스 이름을 추가하여 기본 클래스를 지정합니다.

public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}

클래스 선언에 기본 클래스가 포함된 경우 생성자를 제외한 기본 클래스의 모든 멤버를 상속합니다. 자세한 내용은 상속을 참조하세요.

C#의 클래스는 하나의 기본 클래스에서만 직접 상속할 수 있습니다. 그러나 기본 클래스 자체가 다른 클래스에서 상속될 수 있으므로 클래스는 여러 기본 클래스를 간접적으로 상속할 수 있습니다. 또한 클래스는 하나 이상의 인터페이스를 직접 구현할 수 있습니다. 자세한 내용은 인터페이스를 참조하세요.

클래스는 abstract(으)로 선언할 수 있습니다. 추상 클래스에는 시그니처 정의가 있지만 구현이 없는 추상 메서드가 포함됩니다. 추상 클래스는 인스턴스화할 수 없습니다. 추상 클래스는 추상 메서드를 구현하는 파생 클래스를 통해서만 사용할 수 있습니다. 반면, 봉인된 클래스는 다른 클래스에서 파생되는 것을 허용하지 않습니다. 자세한 내용은 Abstract 및 Sealed 클래스와 클래스 멤버를 참조하세요.

클래스 정의는 여러 소스 파일로 분할될 수 있습니다. 자세한 내용은 참조 Partial 클래스 및 메서드합니다.

C# 언어 사양

자세한 내용은 C# 언어 사양을 참조하세요. 언어 사양은 C# 구문 및 사용법에 대 한 신뢰할 수 있는 소스 됩니다.