1. 간단한 생성자
생성자는 클래스의 특별한 메서드로, 객체를 만들 때 자동으로 호출돼. 이 메서드는 객체를 초기화(설정)해 주는 거지: 처음 값을 넣어주거나, 체크를 하거나, 심지어 농담 한 줄 써서 기분도 올려줄 수 있어.
생성자를 쓰면 객체를 만들 때 바로 원하는 상태로 만들 수 있어서, 필드나 프로퍼티를 하나씩 직접 넣는 것보다 훨씬 편하고 안전해. 중요한 파라미터를 한 번에 다 넣으니까, 뭔가 빼먹을 일도 없고.
생성자 없이 하면 코드가 좀 지저분하고 실수도 생기기 쉬워:
Person p = new Person();
p.Name = "율랴";
p.Age = 25; // 나이 안 넣으면 어떡하지?
생성자 쓰면 이렇게 돼:
Person p = new Person("율랴", 25); // 한 번에 다 넣어서 바로 쓸 수 있음!
생성자 문법
생성자는 클래스 이름이랑 똑같은 "메서드"고, 반환값이 없어(void도 없음). 기본 생성자는 이렇게 생겼어:
public class Person
{
// 기본 생성자 (파라미터 없음)
public Person()
{
// 여기서 초기화 코드 쓸 수 있음
}
}
기본 생성자는 아무 파라미터도 안 받고, 클래스의 모든 필드랑 프로퍼티를 기본값으로 초기화해 주는 "보이지 않는 도우미"야:
- 숫자 타입(int, double, float 등)은 0이야.
- 불린 타입(bool)은 false.
- 참조 타입(string이나 다른 클래스)은 null (즉, "아무것도 없음", "객체 참조 없음").
- DateTime은 01.01.0001 00:00:00이야.
생성자 호출하는 방법?
사실 객체 만들 때 new 연산자를 쓰면, 그게 바로 생성자를 호출하는 거야!
Person p = new Person();
만약 네가 생성자를 하나도 안 만들면, C# 컴파일러가 기본 생성자(파라미터 없는 거)를 자동으로 만들어줘. 근데 네가 생성자를 하나라도 만들면, 기본 생성자는 사라지니까 필요하면 직접 추가해야 돼.
예시
우리 앱에 생성자를 추가해보자. 학생 클래스의 간단한 버전이야:
public class Student
{
public string Name;
public int Age;
// 두 개의 파라미터(이름, 나이) 받는 생성자
public Student(string name, int age)
{
Name = name; // 필드에 값 할당
Age = age;
}
}
이제 학생을 이렇게 만들 수 있어:
Student s = new Student("이반", 21);
Console.WriteLine($"{s.Name}: {s.Age} 살"); // 이반: 21 살
- 생성자랑 클래스 둘 다 public으로 선언했어.
- 생성자에서 받은 파라미터로 필드에 값을 넣어줘.
- 이렇게 하면 실수로 빼먹는 걸 막아줘: 객체 만들 때 이름이랑 나이를 꼭 넣어야 하니까.
2. 생성자 파라미터
C#에서는 파라미터가 다른 여러 개의 생성자를 만들 수 있어. 이걸 생성자 오버로드라고 해(메서드 오버로드는 나중에 또 얘기할 거야).
예를 들어, 파라미터 없는 생성자도 추가해보자:
public class Student
{
public string Name;
public int Age;
// 기본 생성자
public Student()
{
Name = "이름없음";
Age = 0;
}
// 파라미터 있는 생성자
public Student(string name, int age)
{
Name = name;
Age = age;
}
}
이제 둘 다 가능해:
Student s1 = new Student(); // 이름: 이름없음, 나이: 0
Student s2 = new Student("올랴", 22); // 이름: 올랴, 나이: 22
생성자에서 유효성 검사하기
생성자는 입력값 "퀄리티" 체크하기 딱 좋은 곳이야. 예를 들어, 학생 나이가 음수면 안 되잖아!
public Student(string name, int age)
{
if (age < 0)
throw new ArgumentException("나이는 음수일 수 없어!");
Name = name;
Age = age;
}
이제 누가 Student("말리쉬", -2) 이렇게 만들려고 하면, 앱이 예외(ArgumentException)를 던져. 이런 식으로 데이터 신뢰성을 "철벽"으로 지킬 수 있어.
3. 복잡한 객체 초기화
실제 앱에서는 객체가 단순한 값만 가지는 게 아니라, 다른 객체도 포함할 수 있어:
public class Group
{
public string GroupName;
public Student[] Students;
public Group(string groupName, Student[] students)
{
GroupName = groupName;
Students = students;
}
}
이제 학생 여러 명이 들어간 그룹을 쉽게 만들 수 있어:
var students = new Student[]
{
new Student("이반", 20),
new Student("마리야", 19)
};
Group g = new Group("그룹-101", students);
필드 기본값으로 초기화하기
가끔은 생성자에 모든 파라미터를 안 넣고, 일부 필드는 기본값으로 두고 싶을 때가 있어. 예를 들어, 이메일이 필수가 아닐 때:
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "unknown@noemail.com"; // 기본값
}
4. Object Initializer로 초기화하기
생성자랑 같이 쓸 수 있는 또 다른 편한 문법이 있어 — 객체 이니셜라이저. 생성자를 호출한 다음에 중괄호 안에 프로퍼티 값을 바로 넣을 수 있어:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
// 생성자는 여전히 추천!
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "";
}
}
Student s = new Student("안톤", 18) { Email = "anton@domain.com" }; // 생성자 + 프로퍼티
이 문법은 생성자에 일부 값만 넣고, 나머지는 나중에 넣고 싶을 때 딱 좋아.
5. 자주 하는 실수와 특징
생성자 쓸 때 초보들이 자주 하는 실수 몇 가지가 있어. 하나씩 쉽게 설명해줄게:
실수 1: 이름 헷갈리기
파라미터랑 필드 이름이 비슷하면(특히 대소문자만 다르면) 헷갈릴 수 있어.
public Student(string Name, int Age) // 대문자!
{
Name = Name; // 어이쿠! 둘 다 파라미터임. 필드는 초기화 안 됨.
}
정답: this로 필드를 명확히 가리키자:
public Student(string name, int age)
{
this.Name = name;
this.Age = age;
}
아니면 아예 이름을 다르게 해도 돼(nameParam, ageParam처럼). 근데 this. 쓰는 게 특히 큰 프로젝트에서는 좋은 스타일이야.
실수 2: 기본 생성자 없음
생성자를 하나라도 만들고, 파라미터 없이 객체를 만들려고 하면 — 컴파일 에러 나!
public class Student
{
public Student(string name) { /*...*/ }
}
// 코드 어딘가에서
Student s = new Student(); // 에러! 파라미터 없는 생성자 없음.
해결: 파라미터 없는 생성자를 명시적으로 추가해:
public Student() { /*...*/ }
실수 3: 무한 재귀 — 생성자가 자기 자신 호출
public Student()
{
// 에러! 자기 자신을 호출해서 무한 재귀.
new Student();
}
GO TO FULL VERSION