241215

lililllilillll·2024년 12월 15일

개발 일지

목록 보기
21/350

✅ 오늘 한 일


  • C# 교과서 읽기


📖 C# 교과서


35 생성자

35.1 생성자

클래스의 구성 요소 중엔 생성자(constructor)라는 메서드가 있다.
개체를 생성하면서 무엇인가를 하고자 할 때 사용되는 메서드.

일반적으로 생성자는 개체를 초기화하는 데 사용됨.
생성자 이름은 클래스 이름과 동일함.

클래스의 인스턴스가 생성될 때 자동으로 생성자가 실행된다.
클래스에 매개변수를 달리하여 생성자를 여러 개 만들 수도 있음.
생성자도 오버로드가 가능함.
this 키워드를 사용해서 다른 생성자를 호출할 수도 있음.

생성자를 사용하여 개체 생성하기

class ConstructorDemo
{
    public ConstructorDemo()
    {
        Console.WriteLine("생성자 호출");
    }

    static void Main()
    {
        ConstructorDemo c = new ConstructorDemo();
    }
}

35.2 매개변수가 있는 생성자 만들기

매개변수가 여러 개인 생성자 만들기

namespace ConstructorParameter
{
    class My
    {
        private string _name;
        private int _age;

        public My(string name, int age)
        {
            this._name = name;
            this._age = age;
        }
        public void PrintMy()
        {
            Console.WriteLine($"이름 : {this._name}, 나이 : {this._age}");
        }
    }
    class ConstructorParameter
    {
        static void Main()
        {
            My my = new My("백승수", 21);
            my.PrintMy();
        }
    }
}

매개변수가 있는 생성자로 원의 넓이를 구하는 프로그램 만들기

using System;

class Circle
{
    private int _radius;

    public Circle(int radius)
    {
        _radius = radius;
    }
    public double GetArea()
    {
        return Math.PI * _radius * _radius;
    }
}

class GetCircleArea
{
    static void Main()
    {
        Circle circle1 = new Circle(5);
        Console.WriteLine(circle1.GetArea());
        Circle circle2 = new Circle(10);
        Console.WriteLine(circle2.GetArea());
    }
}

35.3 클래스에 생성자 여러 개 만들기

클래스에는 매개변수를 달리하여 생성자를 여러 개 만들 수 있다. 이를 생성자 오버로드라 한다.

class ConstructorLog
{
    public ConstructorLog()
    {
        Console.WriteLine("기본 생성자 실행");
    }

    public ConstructorLog(string message)
    {
        Console.WriteLine("오버로드된 생성자 실행 : " + message);
    }

    class ConstructorOverload
    {
        static void Main()
        {
            var log1 = new ConstructorLog();
            var log2 = new ConstructorLog("C#");   
            var log3 = new ConstructorLog("ASP.NET");
        }
    }
}

35.4 정적 생성자와 인스턴스 생성자

클래스의 정적 멤버를 호출할 때 맨 먼저 호출되는 정적 생성자는 static으로 만들고,
인스턴스 생성자는 public 키워드로 만든다.

정적 생성자 (static constructor)

  • 정적 생성자는 클래스의 정적 멤버가 처음 접근될 때 단 한 번만 호출됩니다.
  • 인스턴스를 생성하지 않아도 호출됩니다.
  • 클래스 전체에 걸쳐 단 한 번만 실행되므로, 클래스 레벨의 초기화 작업에 사용됩니다.
  • 명시적으로 호출할 수 없으며, 매개변수를 가질 수 없습니다.

인스턴스 생성자 (public constructor)

  • 인스턴스 생성자는 클래스의 객체를 생성할 때 호출됩니다.
  • public, private, 또는 다른 접근 제한자를 가질 수 있습니다.
  • 여러 개의 인스턴스 생성자를 만들어 오버로드할 수 있습니다.

정적 생성자만 있을 때의 동작

인스턴스를 생성할 수 없습니다. 정적 생성자는 인스턴스와 관계없이 클래스 레벨에서 단 한 번만 호출되므로, 인스턴스 생성자가 없으면 객체를 생성할 수 없습니다.

35.5 this() 생성자로 다른 생성자 호출하기

생성자에서 this()는 자신의 또 다른 생성자를 의미함.
this() 생성자로 매개변수가 있는 생성자에서
매개변수가 없는 생성자를 호출하거나
또 다른 생성자들을 호출할 수 있음.

> class Say
. {
.     private string message = "[1] hello.";
.     public Say() => Console.WriteLine(this.message);
. 
.     public Say(string message) : this()
.     {
.         this.message = message;
.         Console.WriteLine(this.message);
.     }
. }
> new Say("[2] byebye");
[1] hello.
[2] byebye

this() 호출 > this(string message) 호출
이런 순서로 가는 코드.

생성자 포워딩

this() 생성자를 사용하면 생성자를 포워딩(forwarding)하여 다른 생성자에 값을 전달하기 좋다.

> class Money
. {
.     public Money() : this(1000) { }
.     public Money(int money) => Console.WriteLine("Money : {0:#,###}", money);
. }
> var basic = new Money();
Money : 1,000
> var bonus = new Money(2000);
Money : 2,000

기본 생성자에 있는 this(1000)가 인자 있는 다른 생성자를 호출하는 예시.

35.6 생성자를 사용하여 읽기 전용 필드 초기화

필드를 정의할 때 readonly 키워드를 붙여서 읽기 전용 필드를 만들 수 있다.
읽기 전용 필드는 클래스의 생성자로만 초기화가 가능하다.

상수는 선언과 동시에 반드시 초기화해야 에러가 발생하지 않지만,
읽기 전용 필드는 선언과 동시에 초기화도 가능하고 선언한 후 생성자로 초기화할 수도 있다.

36 소멸자

소멸자는 클래스에서 인스턴스화된 개체가 메모리상에서 없어질 때 실행되는 메서드이다.

36.1 종료자

소멸자(destructor)는 종료자(finalizer)라고도 한다.
닷넷의 가비지 콜렉터에서 클래스의 인스턴스를 사용한 후 최종 정리할 때 실행되는 클래스에서
가장 늦게 호출되는 메서드이다.

클래스 이름과 동일한 메서드로 앞에 ~ 붙여서 만든다.

37 메서드와 매개변수

C# 에서는 모든 함수를 클래스 내에 선언하기 때문에,
함수 대신에 메서드라고 한다.

37.1 메서드

메서드는 개체가 수행할 수 있는 기능, 동작, 행위 등을 의미한다.
메서드 이름은 다음과 같이 동사+명사; 형태를 권장한다. ex. GetPrice(), SetPrice()

37.2 메서드의 매개변수 전달 방식

  • 값 전달 방식: 말 그대로 매개변수로 값을 그대로 복사해서 전달
  • 참조 전달 방식(ref): 실제 데이터는 매개변수가 선언된 쪽에서만 저장하고, 호출된 메서드에서는 참조만 하는 형태로 변수 이름만 전달
  • 반환형 전달 방식(out): 메서드를 호출하는 쪽에서 선언만 하고, 초기화하지 않고 전달하면 메서드 쪽에서 해당 데이터를 초기화해서 넘겨주는 방식
  • 가변형 전달 방식(params): 매개 변수 여러 개를 배열형으로 받을 때 params 키워드를 붙인다. 가변 길이 매개변수는 매개변수를 선언할 때 반드시 마지막에 위치해야 함.

값 전달 방식

void ModifyValue(int x)
{
    x = 10; // x의 값만 변경됨
    Console.WriteLine($"Inside Method: {x}");
}

int a = 5;
ModifyValue(a);
Console.WriteLine($"Outside Method: {a}");

그냥 변수 넣으면 메서드 안에서 해당 변수 조작 못한다

참조 전달 방식

void ModifyRef(ref int x)
{
    x = 10; // 원본 값 변경
    Console.WriteLine($"Inside Method: {x}");
}

int a = 5;
ModifyRef(ref a);
Console.WriteLine($"Outside Method: {a}");

ref 붙여서 변수 넣으면 메서드 안에서 해당 변수 조작 가능하다.
포인터랑 비슷한듯?

반환형 전달 방식

void InitializeOut(out int x)
{
    x = 10; // 반드시 초기화 필요
    Console.WriteLine($"Inside Method: {x}");
}

int a; // 초기화하지 않음
InitializeOut(out a);
Console.WriteLine($"Outside Method: {a}");

메서드한테 해당 변수 초기화까지 맡겨버린다.
return은 반환을 하는거고, 이건 ref에 값 넣는 과정

ref와 out의 차이

ref: 메서드 호출 전에 반드시 변수 초기화해야 함.
out: 메서드 호출 전에 초기화 안 해도 되고, 메서드 내부에선 반드시 초기화해야 함.

ref: ref는 입력으로도 사용되기 때문에 기존 값을 변경할 수 있다는 의미를 가짐.
out: 출력 전용이므로 초기값은 중요하지 않고, 메서드 내부에서 값을 설정해서 반환하겠다는 의미를 가짐.

날짜 형태의 문자열을 날짜형으로 변환: out 키워드 사용하기

자료형.TryParse("변환할 내용", out "변환이 되면 담을 그릇")
if (DateTime.TryParse("2020-01-01", out var myDate))
{
	Console.WriteLine(myDate);
}

37.3 가변 길이 매개변수

class Program
{
    // params 키워드를 사용한 메서드
    static int AddNumbers(params int[] numbers)
    {
        int sum = 0;
        foreach (int num in numbers)
        {
            sum += num;
        }
        return sum;
    }

    static void Main()
    {
        // 1. 개별적으로 값을 나열해서 전달
        int result1 = AddNumbers(1, 2, 3, 4, 5);
        Console.WriteLine($"Sum 1: {result1}");

        // 2. 배열로 값을 전달
        int[] numbersArray = { 10, 20, 30 };
        int result2 = AddNumbers(numbersArray);
        Console.WriteLine($"Sum 2: {result2}");
    }
}

params 쓰면 매개변수 여러 개 한꺼번에 보낼 수 있다.

37.4 메서드 본문을 줄여 표현하기

식 본문 메서드 사용하기

static void Walk() => Console.WriteLine("Walk");

화살표 연산자를 이용하여 메서드 본문을 줄여 표현할 수 있다.

단일 표현식의 메서드를 한 줄로 정의하기

결괏값이 하나인 단일 표현식일 때는 화살표 기호로 메서드 본문을 줄여 표현할 수 있다.

static int AddAge(int age) => age + 1; // return age + 1의 축약 형식

37.5 선택적 매개변수

> static int Add(int a, int b = 1)
{
	return a+b;
}
> Add(5)
6
> Add(5,3)
8

기본값 넣어주면 사용할 때 인자 넣어줘도 되고 안 넣어줘도 되고.
이걸로 메서드 오버로드한 효과 낼 수 있다.

명명된 매개변수

Console.WriteLine(Sum(second: 3, first: 2));

순서 상관 없이 매개변수에 값 직접 할당 가능



profile
너 정말 **핵심**을 찔렀어

0개의 댓글