1. 객체 생성하기
드디어 객체 생성까지 왔네. 사실 너희가 이미 이걸 전에 봤을 거야, 근데 이제 좀 더 자세히 파헤쳐볼 거야. 사실 객체 만드는 건 엄청 쉬워.
객체를 만들려면 new 연산자를 써야 해. 보통은 클래스의 새 인스턴스(객체)를 만들고, 그걸 같은 타입의 변수에 바로 저장하지.
클래스 이름 = new 클래스(파라미터);
여기서 클래스 — 객체 타입, 이름 — 변수 이름(보통 소문자로 시작, 예를 들면 cat), 그리고 = 오른쪽엔 그 클래스의 새 객체를 만드는 거야.
예시:
| 코드 | 설명 |
|---|---|
|
object 타입 객체 생성 |
|
Cat 타입 객체 생성 |
|
파라미터와 함께 StreamReader 객체 생성 |
프로그래머들은 변수 이름을 클래스 이름이랑 똑같이(근데 소문자로 시작) 짓는 경우가 많아. 초보자들은 이런 코드가 헷갈릴 수도 있어:
| 코드 |
|---|
|
|
|
사실 이런 코드엔 아무 문제 없어 — 그냥 변수 선언하고, 그 타입의 객체로 바로 초기화하는 거야.
왼쪽은 변수 선언, 오른쪽은 new로 메모리에 새 객체를 만드는 거지. 끝!
2. 생성자
아마 객체 만들 때 파라미터를 넘기는 걸 자주 봤을 거야. 어떤 객체엔 파라미터를 넘기고, 어떤 건 그냥 만들고... 이 파라미터 시스템이 어떻게 동작하는지 궁금하지?
이것도 쉬워: 각 클래스엔 특별한 메서드(혹은 여러 개)가 있는데, 객체 생성 시 파라미터를 처리해. 이런 메서드를 생성자라고 해. 하나면 생성자지.
생성자 메서드는 일반 메서드랑 구분하기 쉬워. 두 가지 특징이 있어:
- 생성자 메서드 이름은 클래스 이름이랑 똑같아 (대문자로 시작)
- 생성자 메서드는 리턴 타입이 없어 (void도 안 씀).
보통 이렇게 생겼어:
수식어 클래스(파라미터)
{
생성자 코드
}
생성자 선언 예시:
public class Point
{
public int X;
public int Y;
public Point(int x, int y) // 생성자
{
X = x;
Y = y;
}
}
사용법:
Point p = new Point(5, 10); // 생성자 호출
new Point(5, 10)으로 객체를 만들면, 두 개 파라미터를 받는 생성자가 호출되고, X와 Y 필드가 초기화돼.
가끔 생성자 파라미터랑 필드 이름이 똑같을 때가 있어 — 편하니까. 이런 이름 충돌은 키워드 this로 해결해:
public Point(int x, int y)
{
this.x = x; // this.x — 객체 필드, x — 생성자 파라미터
this.y = y;
}
3. 생성자 호출
new 클래스(파라미터)를 쓰면, C#은:
- 메모리에 새 객체를 만들고,
- 네가 넘긴 파라미터로 맞는 생성자를 호출해.
고양이 클래스 예시:
public class Cat
{
public string Name;
public int Age;
public Cat(string name, int age)
{
Name = name;
Age = age;
}
}
사용법:
Cat cat = new Cat("바스카", 2); // 가능: 두 파라미터 생성자 호출
Cat cat2 = new Cat("바스카"); // 불가: 그런 생성자 없음 — 컴파일 에러
Cat cat3 = new Cat(); // 불가: 파라미터 없는 생성자 없음 — 컴파일 에러
클래스에 파라미터 있는 생성자만 있으면, 객체 만들 때 꼭 값을 넘겨야 해.
4. 여러 개의 생성자
근데 필요하면 클래스에 생성자를 여러 개 넣을 수 있어. 생성자 개수나 파라미터엔 제한 없어. 객체 만들 때 컴파일러가 파라미터에 맞는 생성자를 골라서 써.
예시:
public class Cat
{
public const int UNKNOWN = -1;
public string Name;
public int Age;
public Cat(string name, int age)
{
Name = name;
Age = age;
}
public Cat(string name)
{
Name = name;
Age = UNKNOWN; // 나이 모를 때 기본값
}
}
사용법:
Cat cat1 = new Cat("바스카", 2); // 첫 번째 생성자 사용
Cat cat2 = new Cat("무르카"); // 두 번째 생성자 사용
Cat cat3 = new Cat(); // 에러! 파라미터 없는 생성자 없음
고양이 나이를 모를 수도 있으니까, UNKNOWN이라는 상수를 만들고, 이름만 받는 생성자도 추가했어.
여전히 두 생성자 모두에서 클래스 변수 둘 다 초기화하는 거 잊지 마. 없는/모르는 파라미터는 UNKNOWN으로 대체해.
5. 기본 생성자
클래스에 생성자가 하나도 없으면, 컴파일러가 자동으로 파라미터 없는 빈 생성자를 추가해:
public ClassName()
{
}
근데 클래스에 생성자가 하나라도 있으면, 자동으로 빈 생성자 더 이상 안 만들어져.
예시 1:
public class Cat
{
public string Name;
public int Age;
}
// 가능:
Cat cat = new Cat(); // 기본 생성자(파라미터 없음) 호출됨
예시 2:
public class Cat
{
public string Name;
public int Age;
public Cat(string name) { Name = name; }
}
// 불가:
Cat cat = new Cat(); // 에러: 파라미터 없는 생성자 없음!
6. 변수 초기화
C#에선 클래스 변수를 선언할 때 바로 초기화하거나, 생성자에서 초기화할 수 있어.
예시:
public class Cat
{
public string Name;
public int Age = -1; // 시작값
public Cat(string name, int age)
{
Name = name;
Age = age; // 시작값 덮어씀
}
public Cat()
{
Name = "이름없음";
// Age는 -1(시작값) 그대로
}
}
설명:
- new Cat("바스카", 2)로 만들면 Age는 처음엔 -1이지만, 생성자에서 2로 바뀜.
- new Cat()로 만들면 Age는 -1 그대로야.
7. 변수 초기화 순서
새 객체의 데이터는 이런 순서로 초기화돼:
- 클래스 필드가 먼저 기본값을 받아 (0은 int에, null은 참조 타입 등).
- 그 다음, 네가 필드 선언할 때 쓴 초기화 코드가 순서대로 실행돼.
- 그리고 마지막에 생성자 코드가 실행돼.
변수들은 생성자 전에 그리고 선언 순서대로 초기화돼. 그래서 필드들끼리 의존관계가 있다면 조심해야 해.
잘못된 예시
non-static 필드는 다른 non-static 변수로 초기화할 수 없어:
public class Solution
{
public int a = 1;
public int b = a; // a 사용 불가
public int c = a + b; // a, b 사용 불가
}
// 이런 코드는 컴파일 에러!
올바른 예시
static 변수는 잘 동작해:
public class Solution
{
public static int a = 1; // a = 1
public static int b = a + 2; // b = 1 + 2 ⇒ 3
public static int c = a + b + 3; // c = 1 + 3 + 3 ⇒ 7
public Solution()
{
Console.WriteLine($"a = {a}, b = {b}, c = {c}");
// 출력: a = 1, b = 3, c = 7 — 기대한 그대로
}
}
올바른 예시 2
static 필드는 이렇게도 쓸 수 있어:
public class Solution
{
public static int a = b + c + 1; // b, c는 아직 0
public static int b = a + c + 2; // a == 1, c는 아직 0
public static int c = a + b + 3; // a == 1, b == 3
}
GO TO FULL VERSION