Search

이것이 C#이다: 7장 - 클래스 (1/3)

서론

C#은 객체 지향 프로그래밍 언어로, 클래스는 그 핵심 구성 요소입니다. 클래스는 객체의 청사진 역할을 하며, 데이터와 해당 데이터를 조작하는 메서드를 캡슐화합니다. 클래스를 제대로 이해하고 활용하는 것은 효율적이고 유지보수가 용이한 C# 프로그램을 작성하는 데 필수적입니다.
이번 포스트에서는 C# 클래스의 주요 개념인 생성자와 종료자, 객체 복사, this 키워드, 그리고 접근 한정자에 대해 자세히 살펴보겠습니다.

본론

1. 생성자와 종료자

1.1 생성자 (Constructor)

생성자는 객체가 생성될 때 자동으로 호출되는 특별한 메서드입니다. 객체의 초기화를 담당하며, 클래스와 동일한 이름을 가집니다.
public class Person { public string Name; public int Age; // 기본 생성자 public Person() { } // 매개변수를 받는 생성자 public Person(string name, int age) { Name = name; Age = age; } }
C#
복사
주목할 점은 명시적으로 생성자를 구현하지 않아도 컴파일러가 기본 생성자를 제공한다는 것입니다. 하지만 하나라도 생성자를 직접 정의하면, 컴파일러는 기본 생성자를 제공하지 않습니다.

1.2 종료자 (Finalizer)

종료자는 객체가 소멸될 때 호출되는 메서드입니다. 하지만 C#에서는 가비지 컬렉터가 메모리 관리를 담당하기 때문에, 종료자의 사용은 권장되지 않습니다.
public class ResourceHeavyClass { ~ResourceHeavyClass() { // 리소스 정리 코드 } }
C#
복사
종료자 사용 시 주의점:
1.
실행 시점을 예측할 수 없습니다.
2.
성능 저하를 초래할 수 있습니다.
3.
대부분의 경우 IDisposable 인터페이스를 구현하는 것이 더 적절합니다.
개인적으로 종료자를 직접 사용한 경우가 극히 드물긴 했습니다. 하드웨어와 밀접한 자원 관리 클래스 정도에서 사용했던 기억이 있습니다.

2. 객체 복사

C#에서 객체를 복사할 때는 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)의 차이를 이해하는 것이 중요합니다.

2.1 얕은 복사 (Shallow Copy)

얕은 복사는 객체의 참조만을 복사합니다. 클래스 타입 변수를 다른 변수에 할당할 때 기본적으로 얕은 복사가 일어납니다.
Person person1 = new Person("Alice", 30); Person person2 = person1; // 얕은 복사
C#
복사
이 경우, person1person2는 같은 객체를 참조합니다.

2.2 깊은 복사 (Deep Copy)

깊은 복사는 객체의 모든 멤버를 새로운 메모리 공간에 복사합니다. C#에서는 깊은 복사를 자동으로 수행해주는 기능이 없어, 직접 구현해야 합니다.
public class Person : ICloneable { public string Name; public int Age; public object Clone() { return new Person(this.Name, this.Age); } } // 사용 Person person1 = new Person("Bob", 25); Person person2 = (Person)person1.Clone(); // 깊은 복사
C#
복사
ICloneable 인터페이스를 구현하면 .NET의 다른 클래스들과의 호환성을 유지할 수 있습니다.

3. this 키워드

this 키워드는 현재 인스턴스를 참조합니다. 주로 다음과 같은 상황에서 사용됩니다:
1.
매개변수와 필드의 이름이 같을 때 구분하기 위해
2.
현재 인스턴스를 다른 메서드의 인자로 전달할 때
3.
생성자 체이닝(Constructor chaining)을 위해

3.1 멤버 접근

public class Person { private string name; public void SetName(string name) { this.name = name; // 매개변수와 필드 이름이 같을 때 구분 } }
C#
복사

3.2 생성자 체이닝

public class Person { public string Name; public int Age; public Person(string name) : this(name, 0) { } public Person(string name, int age) { Name = name; Age = age; } }
C#
복사

4. 접근 한정자

접근 한정자는 클래스의 멤버에 대한 접근 수준을 결정합니다. C#은 다음과 같은 접근 한정자를 제공합니다:
접근 한정자
설명
public
어디서든 접근 가능
private
같은 클래스 내에서만 접근 가능
protected
같은 클래스 및 파생 클래스에서 접근 가능
internal
같은 어셈블리 내에서 접근 가능
protected internal
같은 어셈블리 내 또는 파생 클래스에서 접근 가능
private protected
같은 어셈블리 내의 파생 클래스에서만 접근 가능
public class Person { private string name; // 클래스 내부에서만 접근 가능 public int Age; // 어디서든 접근 가능 protected void InternalMethod() { } // 파생 클래스에서 접근 가능 }
C#
복사

참고 자료

박상현, "이것이 C#이다", 한빛미디어, 2023