C#

[C#]생성자(Constructor)

DevStory 2022. 5. 5.

생성자(Constructor)

C#의 생성자는 클래스 인스턴스(객체)를 생성할 때마다 자동으로 실행되는 특수한 메서드입니다. 생성자는 클래스 내부에 존재하며, 두 가지 역할을 담당합니다.

 

첫 번째는 객체를 초기화하는 역할을 담당하고 두 번째 역할은 메모리 할당입니다. new 키워드를 사용하여 클래스 인스턴스를 생성할 수 있습니다.


생성자 특징

  1. 생성자 이름은 클래스 이름과 동일합니다.
  2. 생성자는 값을 반환하지 않으므로 반환 유형과 return문이 존재하지 않습니다.
  3. 생성자를 정의하지 않으면 클래스에서 기본 생성자라고 하는 암시적 생성자를 제공합니다.

생성자 예제

다음은 Program 클래스의 인스턴스를 생성하고 기본 생성자가 실행되는 예제입니다.

class Program
{
  Program()
  {
    Console.WriteLine("Person 클래스의 기본 생성자 호출");
  }

  static void Main(string[] args)
  {
    Program program = new Program();
  }
}

실행 결과

Person 클래스의 기본 생성자 호출

Program 클래스의 Program() 메서드는 생성자이므로 반환 타입이 없습니다. 메서드 이름은 클래스 이름과 동일하며, 접근 지정자(접근 제한자)를 생략하면 public으로 선언됩니다.

 

Main 문에서 Program 클래스의 인스턴스를 생성하면 생성자의 내부 코드가 실행됩니다. 


5가지 유형의 생성자

  1. 기본 생성자
  2. 매개변수가 존재하는 생성자
  3. 정적 생성자
  4. 복사 생성자
  5. Private 생성자

C#에는 5가지 유형의 생성자가 존재합니다. 정적 생성자를 제외하고 4가지 유형의 생성자를 살펴보겠습니다.

 

정적 사용자는 내용이 길어서 이번 포스팅에서 설명하기 어려우며, 다음 포스팅에서 설명할 것입니다.


기본 생성자

매개변수가 없는 생성자를 기본 생성자라고 하며, 기본 생성자는 시스템 정의 기본 생성자, 사용자 정의 기본 생성자로 분류됩니다.


시스템 정의 기본 생성자

클래스 내부에 생성자를 정의하지 않은 경우 기본적으로 시스템은 컴파일 시 하나의 생성자를 제공합니다. 이 생성자는 클래스 필드(non-static 변수)에 기본 값을 할당하며, 시스템에 의해 생성되므로 시스템 정의 기본 생성자라고도 합니다.

 

다음은 사용자 정의 기본 생성자 예제입니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
  
  public override string ToString() {
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person = new Person();

    Console.WriteLine(person.ToString());
  }
}

실행 결과

Name: , Age: 0

사용자 정의 기본 생성자

매개변수가 없는 생성자에서 특정 로직을 작성한 경우 사용자 정의 기본 생성자라고 합니다.

 

다음은 사용자 정의 기본 생성자 예제입니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
  
  public Person()
  {
    name = "Tom";
    age = 20;
    Console.WriteLine("기본 생성자 호출!");
  }
        
  public override string ToString() {
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person = new Person();

    Console.WriteLine(person.ToString());
  }
}

실행 결과

기본 생성자 호출!
Name: Tom, Age: 20

즉, 클래스 내부에서 기본 생성자를 명시하고 특정 로직 또는 코드가 존재하는 경우 사용자 정의 기본 생성자라고 말합니다.

반응형

매개변수가 존재하는 생성자

매개변수가 있는 생성자는 이름 그대로 생성자에 매개변수가 존재합니다. 생성자에 매개변수를 전달하여 클래스의 각 인스턴스를 다른 값으로 초기화할 수 있습니다.

 

다음은 매개변수가 존재하는 생성자 예제입니다.

class Person
{
  string name { get; set; }
  int age { get; set; }

  // name 필드를 초기화하는 생성자
  public Person(string name)
  {
    this.name = name;
  }
  
  // age 필드를 초기화하는 생성자
  public Person(int age)
  {
    this.age = age;
  }
  
  // name, age 둘 다 초기화하는 생성자
  public Person(string name, int age)
  {
    this.name = name;
    this.age = age;
  }

  public override string ToString() { 
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person("Tom");
    Person person2 = new Person(20);
    Person person3 = new Person("Bob", 40);

    Console.WriteLine(person1.ToString());
    Console.WriteLine(person2.ToString());
    Console.WriteLine(person3.ToString());
  }
}

실행 결과

Name: Tom, Age: 0
Name: , Age: 20
Name: Bob, Age: 40

C#의 클래스 내부에서 생성자를 원하는 개수만큼 정의할 수 있습니다. 중요한 점은 모든 생성자는 다른 매개변수를 가져야 한다는 점입니다.

 

주의사항으로 클래스에 매개변수가 존재하는 생성자가 존재하는 경우 기본 생성자를 명시해야 합니다. 다음 예제를 실행하면 컴파일 에러가 발생합니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
        
  public Person(string name, int age)
  {
    this.name = name;
    this.age = age;
  }

  public override string ToString() { 
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person("Bob", 40);

    // 기본 생성자가 없어서 컴파일 에러 발생
    Person person2 = new Person();
  }
}

실행 결과

클래스에 매개변수가 존재하는 생성자가 있는 경우 컴파일러는 기본 생성자를 제공하지 않으므로 매개변수가 없는 생성자(기본 생성자)를 구현할 필요가 있습니다.


복사 생성자

생성자에서 동일한 클래스의 객체를 매개변수로 사용하는 경우 복사 생성자라고 말합니다. 복사 생성자의 주요 목적은 기존 객체를 매개변수로 전달하여 새로운 객체를 초기화하는 것입니다.

 

다음은 복사 생성자 예제입니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
  
  public Person(string name, int age)
  {
    this.name = name;
    this.age = age;
  }

  public Person(Person person)
  {
    this.name = person.name;
    this.age = person.age;
  }
  
  public override string ToString() { 
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person("Bob", 40);

    Person person2 = new Person(person1);

    Console.WriteLine(person1.ToString());
    Console.WriteLine(person2.ToString());
  }
}

실행 결과

Name: Bob, Age: 40
Name: Bob, Age: 40

private 생성자

private 생성자는 생성자의 접근 지정자를 private로 설정합니다. private로 설정하는 경우 클래스 외부에서 클래스 객체를 생성할 수 없습니다. 따라서 private 생성자는 동일한 클래스 내에서 클래스 인스턴스(객체)를 생성하는 경우 사용됩니다.

 

다음은 private 생성자 예제입니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
  
  Person()
  {
    Console.WriteLine("기본 생성자 실행!");
  }

  private Person(string name, int age)
  {
    this.name = name;
    this.age = age;
  }

  public override string ToString() { 
    return "Name: " + this.name + ", Age: " + this.age; 
  }
}

class Program
{
  static void Main(string[] args)
  {
    Person person1 = new Person();
    Person person2 = new Person("Bob", 20);
  }
}

실행 결과

Person 클래스에 private 생성자가 존재하므로 Person 클래스 외부인 Program 클래스의 Main문에서 Person 클래스의 인스턴스를 생성할 수 없습니다.

 

Person 클래스의 인스턴스를 생성하기 위해서는 다음 예제처럼 Person 클래스 내부에서 인스턴스를 생성해야 합니다.

class Person
{
  string name { get; set; }
  int age { get; set; }
  
  Person() 
  { 
    Console.WriteLine("기본 생성자 실행!"); 
  }
  
  private Person(string name, int age) 
  {
    Console.WriteLine("private 생성자 실행!");
    this.name = name; 
    this.age = age; 
  }
  
  public override string ToString() 
  { 
    return "Name: " + this.name + ", Age: " + this.age; 
  }
    
  static void Main(string[] args) 
  {
    Person person1 = new Person(); 
    Person person2 = new Person("Bob", 20); 
  }
}

실행 결과

기본 생성자 실행!
private 생성자 실행!
반응형

'C#' 카테고리의 다른 글

[C#]정적 생성자(Static Constructor)  (0) 2022.05.05
[C#]복사 생성자(Copy Constructor)  (0) 2022.05.05
[C#]소멸자(destructor)  (0) 2022.05.02
[C#]DataTable을 List로 변환  (0) 2022.05.01
[C#]텍스트 파일 쓰기  (0) 2022.05.01

댓글