본문 바로가기

C# 일기

22. this와 this생성자 this()

클래스의 내용을 작성할 때. 특히, 생성자를 작성할 때, this라는 키워드를 사용해서 아래와 같이 매개와 멤버를 구분하곤 한다.

 

class Favor
{
   private string name;
   
   public Favor(string name)
   {
      this.name = name;
   }
}

 

위와 같이 매개변수로 설정한 변수의 이름과, 멤버변수의 이름이 같을 때, 이를 구분짓기 위해 멤버변수의 이름 앞에 this한정자를 붙여 매개변수의 이름과 구분할 수 있다.

 

 

 

 

 

생성자도 오버라이딩이 가능하다. 

 

클래스를 객체화할 때, 생성자의 매개변수를 서로 다르게 하여, 아래와 같이 같은 클래스에서 다형성을 갖춘 객체를 생성할 수 있다.

  

class MyClass
{
    int a, b, c;
    public MyClass() { a = 1; }

    public MyClass(int b)
    {
        a = 1;
        this.b = b;
    }

    public MyClass(int b, int c)
    {
        a = 1;
        this.b = b;
        this.c = c;
    }
}

 

위처럼 생성된 클래스의 생성자를 통해, 매개변수를 하나도 입력하지 않는다면 a의 값이 1인 객체가,

매개변수를 하나 입력한다면 a = 1이고, b의 값에 전달한 매개변수의 값을 갖게되는 객체가,

매개변수를 두개 입력한다면 a = 1, b의 값은 첫번째 매개변수, c의 값은 두번째 매개변수의 값을 갖게되는 객체가 생성되어,

총 3개의 서로다른 객체가 인스턴스된다.  

 

 

 

하지만 위와같이 생성자를 오버라이딩 했을 때, 계속 이전의 코드를 입력해야 하므로 코드의 재사용성이 떨어지게 된다.

 

위의 예시는 한 줄 뿐인 내용을 다시 적었을 뿐이었지만, 한 줄 이상의 내용이 작성되야 한다면, 작업의 효율이 크게 떨어진다.

 

이를 위하여 this키워드는 멤버변수의 구분 뿐만 아니라, 생성자의 재호출 기능도 담당하고 있다.

 

this 생성자는 클래스 내부에서 생성자를 만들때 호출할 수 있는 함수로, 자신이 속해있는 클래스의 생성자를 재호출하는 역할을 한다.

 

this생성자의 호출 방법은 아래와 같다. 위의 코드에서 작성한 내용과 동일한 코드를 this생성자를 통해 다시 만들어보자.

 

 

 

 

class MyClass1
{
    int a, b, c;
    public MyClass1() 
    {
        a = 1; 
    }

    public MyClass1(int b) : this()     // 매개가 없는 자신의 생성자를 호출한 후,
    {
        // 코드의 내용을 실행할 것.
        this.b = b;
    }

    public MyClass1(int b, int c) : this(b)  // 매개를 하나 받는 자신의 생성자를 호출한 후,
    {
        // 코드의 내용을 실행할 것.
        this.c = c;
    }
}

 

중복 입력된 코드가 전부 사라지고, 클래스를 상속받았을 때 사용했던 : 가 등장했다.

 

주석 처리한 내용과 같이, 생성자 뒤에  : this() 생성자를 입력하면, this()생성자를 호출한 다음, 해당 생성자가 실행된다.

 

여기서 볼 수 있는 this 생성자의 종류는 총 두가지인데, 하나는 this()이고, 하나는 this(b)이다.

 

this()는 매개변수를 입력해야하는 자리인 소괄호 속에 아무것도 작성되어있지 않으므로, 본인이 속한 클래스의 생성자중, 매개변수를 전달받지 않는 생성자를 호출한다는 뜻이다.

 

그럼 자연스럽게 this(b)의 의미가 어떤 것인지도 유추가 가능하다.

 

this(b)는 매개변수 하나를 전달받는 생성자를 호출한다는 뜻이고, 해당 생성자의 매개변수로 본인이 선언한 생성자인 int b를 대입하겠다는 뜻이다.

 

MyClass1(int b, int c) 생성자는 매개변수로 int b와 int c를 전달받는다.

 

이 때 전달받은 int b를 매개변수 하나를 전달받는 생성자에게도 넘겨준다는 뜻이다.

 

여기서 매개변수 하나를 전달받는 생성자는 MyClass1(int b)이기 때문에, 해당 생성자를 호출하면서 매개변수로 자신이 입력받은 변수인 int b를 전달한 채로 생성자가 실행된다.

 

 

 

class MyClass1
{
    int a, b, c;
    public MyClass1() 
    {
        a = 1; 
    }

    public MyClass1(int b) : this()     // 매개가 없는 자신의 생성자를 호출한 후,
    {
        // 코드의 내용을 실행할 것.
        this.b = b;
    }

    public MyClass1(int b, int c) : this(b)  // 매개를 하나 받는 자신의 생성자를 호출한 후,
    {
        // 코드의 내용을 실행할 것.
        this.c = c;
    }
}

static void Main(string[] args)
{
   MyClass1 my = new MyClass1(2, 3);
}

 

위처럼 클래스를 객체화 했을때의 순서를 살펴보자.

 

매개변수 두개를 전달했기 때문에 맨 마지막 생성자가 호출될 것이다.

 

마지막 생성자가 호출되기 전, 매개변수 하나를 전달받는 생성자가 호출되고, 해당 생성자에 int b에 해당하는 2의 값을 전달한다.

 

b를 전달받은 두번째 생성자가 호출되기 전, 매개변수가 없는 생성자가 호출되어 a의 값이 1이된다.

 

그 다음 두번째 생성자가 호출되어 b의 값에 2가 대입되고,

 

마지막으로 세번째 생성자가 호출 되어 c의 값에 3이 대입되어

 

my의 a, b, c의 값은 1, 2, 3이 대입된다.

 

 

 

 

 

 

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

24. Stack  (0) 2024.03.12
23. IEnumerable과 yield  (0) 2024.03.12
21. 일반화 대리자 Func VS Action  (0) 2024.03.12
20. 람다식(Lambda Expression)  (0) 2024.03.11
19 - 1. 이벤트 VS 대리자  (0) 2024.03.11