I'm FanJae.
[20260504] C# (프로퍼티, 생성자, 메서드 II) 본문
1. 프로퍼티 (Property)
1) 정의
- 필드를 외부에 공개하지 않고 안전하게 접근할 수 있도록 도와주는 접근자이다.
- 내부 데이터는 숨기고, getter/setter를 통해 제어된 방식으로 접근할 수 있다.
2) 목적
- 잘못된 값이 들어오는 것을 차단하여, 데이터 무결성을 유지한다.
- 필요에 따라 접근 수준을 제어할 수 있다. (읽기•쓰기 中 특정 프로퍼티만 제공도 가능하다.)
- 메서드 형태의 호출 방식보다 대입 연산자를 사용하는 방식이 보기 편하다.
3) 종류
① 기본 프로퍼티
class Character // 캐릭터 클래스
{
private string name; // 이름 필드
public string Name // 이름 프로퍼티
{
get { return name; } // getter
set { name = value; } // setter
}
}
(1) 각 문장별 의미
- private string name : 데이터를 저장하는 필드
- private string Name : 외부에서 접근하는 프로퍼티
- get : 값 읽기
- set : 값 쓰기
- value : 키워드다. Name = "Knight" 처럼 대입된 값을 의미한다.
※ 일반적으로 필드는 private으로 두고, public 프로퍼티를 제공한다.
② 읽기 전용 프로퍼티 (setter가 없는 형태)
class Character // 캐릭터 클래스
{
private int level; // 레벨 필드
public int Level
{
get { return level; } // getter
}
}
- setter가 없기 때문에, 외부에서 값 변경을 허용하지 않는다.
③ 쓰기 전용 프로퍼티 (getter가 없는 형태)
class Sign // 표지판 클래스
{
private string message; // 메시지 필드
public string Message
{
set { message = value; } // setter
}
}
- getter가 없기 때문에, 외부에서 값 읽기를 허용하지 않는다.
④ 자동 구현 프로퍼티
class Character
{
public string Name { get; set; }
}
- 위와 같이 구현하면, 내부 필드를 컴파일러가 자동으로 생성한다.
- get과 set 에 내부 로직이 필요 없을때 사용한다.
- 코드가 간결하고 유지보수가 쉬운 이점이 있다.
⑤ 검증 로직 포함 프로퍼티 (Validation Logic In Property)
class Player
{
private int hp;
public int Hp // Hp Property
{
get { return hp; }
set
{
if (value < 0) // 입력 받은 값이 0 이하로 내려갔으면 HP 0으로 변경
{
if (hp > 0)
{
Console.WriteLine($"Player : {name}가 사망하였습니다.");
}
hp = 0;
}
else if (value > 100) // 입력 받은 값이 100 넘어갔으면 HP 100으로 최대값 조정
{
hp = 100;
Console.WriteLine($"Player : {name}의 체력이 {value}으로 설정 -> HP: {hp}");
}
else
{
hp = value;
}
}
}
}
- 위 예제에서 setter는 데이터 유효성을 보장하고 있다.
- 값을 단순히 막는 것이 목표가 아닌 유효한 범위 내 데이터 입력을 보장하는 것이다.
⑥ private set
class Inventory
{
private int capacity;
private int count;
public Inventory(int capacity)
{
Capacity = capacity;
Count = 0;
}
public int Capacity
{
get { return capacity; }
private set { capacity = value; }
}
public int Count
{
get { return count; }
private set { count = value; }
}
public void AddItem()
{
// Item Add
Count++;
}
public void DeleteItem()
{
// Item Delete
Count--;
}
}
Inventory data = new Inventory(5);
Console.WriteLine(data.Count); // 가능
data.Count = 5; // 불가능
- Count 값은 외부에서 직접 바꾸지 못한다.
- AddItem() 이나 DeleteItem() 과 같은 클래스 내부 메서드를 통해서만 변경될 수 있다.
2. 생성자 (Constructor)
1) 정의
- 객체가 생성될 때 자동으로 호출되는 특수한 메서드이다.
- 객체의 초기 상태를 설정할 때 사용한다.
2) 특징
- 생성자의 이름은 클래스의 이름과 동일하다.
- 생성자는 반환형이 없다.
- new 로 객체를 생성시 자동으로 호출한다.
- 사용자 정의 생성자가 없으면 기본 생성자를 생성한다.
3) 기본 형태
① 기본 생성자
class Character
{
private string name;
private int level;
public Character()
{
name = "초보자";
level = 1;
Console.WriteLine("기본 캐릭터가 생성되었다.");
}
public string Name
{
get { return name; }
set { name = value; }
}
public int Level
{
get { return level; }
set { level = value; }
}
}
- 가장 기본적인 생성자로 매개변수가 없는 형태의 생성자다.
② 생성자 오버로딩
- 생성자 오버로딩은 매개 변수가 다른 생성자를 여러 개 만드는 것을 의미한다.
public Character()
public Character(string name)
public Character(string name, int level)
- 각 생성자는 객체를 생성하는 방식에 따라 다르게 호출 될 수 있다.
Character c1 = new Character();
Character c2 = new Character("FanJae");
Character c3 = new Character("Master",100);
(1) 생성자 오버로딩을 사용하는 이유
- 객체 초기화 방식을 다양하게 제공하기 위해서 사용한다.
4) 생성자의 호출 순서
- 생성자 호출 순서는 상속 관계에서 중요하다.
- 부모 클래스의 생성자가 먼저 호출되고, 자식 클래스 생성자가 실행된다.
- 이는 상속에서 자세히 다룬다.
5) 생성자 체이닝 (Constructor Chaining)
(1) 정의
- 한 생성자가 같은 클래스의 다른 생성자를 호출해서 초기화 로직을 재사용하는 방식이다.
public Character() : this("초보자", 1)
{
}
public Character(string name) : this(name, 1)
{
}
public Character(string name, int level)
{
Name = name;
Level = level;
}
Character c1 = new Character();
- 위와 같은 순서라면, 생성자는 아래 순서로 호출된다.
Character()
-> Character("초보자", 1)
-> 실제 초기화 진행.
(2) 사용하는 이유
- 생성자 오버로딩을 할 때, 중복 코드가 생기기 쉽다.
- 생성자 체이닝을 이용하면 중복 코드를 줄일 수 있다.
3. 메서드와 static
1) 종류
(1) 인스턴스 메서드 (Instance Method)
- 클래스의 인스턴스를 생성한 후에 호출할 수 있는 메서드이다.
- 특정 객체의 상태를 변경하거나 참조가 가능하다.
Character ch = new Character();
ch.ShowLevel(); // 인스턴스 메서드
(2) 정적 메서드 (static Method)
- 객체를 생성하지 않고 클래스 이름으로 호출하는 메서드
- static 키워드를 사용한다.
- 인스턴스 필드에 직접 접근할 수 없다.
- 정적 필드에만 접근할 수 있다.
class Calculator
{
// 정적 메서드 정의
public static int Add(int a, int b)
{
return a + b;
}
}
class Program
{
static void Main()
{
int result = Calculator.Add(50,100);
Console.WriteLine(result);
}
}
- Calculator 내부에 있는 Add() 는 객체 생성 없이 사용할 수 있다.
int result = Math.Max(1,2);
- Max 는 System.Math 클래스의 Max 메서드로 대표적인 정적 메서드이다.
- Math에 대한 객체를 만들지 않아도 Max를 사용할 수 있다. (Math는 static class라서 인스턴스 생성이 불가능한 점도 있다.)
(3) 정적 클래스 (static Class)
- 공통된 기능을 제공하거나, 공유 데이터를 관리할 때 사용한다.
- static 키워드를 사용하여 선언한다.
- 인스턴스 생성을 할 수 없다.
- 상속할 수 없다.
- 정적 변수, 정적 메서드를 포함할 수 있다.
static class MathUtils
{
public static double Pi = 3.141592;
public static int Add(int a, int b)
{
return a + b;
}
public static double CircleArea(double radius)
{
return Pi * radius * radius;
}
}
int max = Math.Max(10, 20);
double pow = Math.Pow(2, 3);
- 앞서 정적 메서드에서 다뤘던 System.Math 가 정적 클래스(static class)이다.
- 따라서 해당 클래스는 인스턴스 생성이 불가능하다.
[정적 클래스의 사용처]
Case 1) 공통적으로 사용되는 기능(유틸리티, 설정, 수학 관련 기능)
- 앞에서 보였던 사례가 대표적이다.
Case 2) 객체마다 다른 값이 필요하지 않고, 하나의 값이 공유되는 경우
static class GameConfig
{
public static int MaxLevel = 200;
public static float DefaultDropSpeed = 5.0f;
}
- 위와 같이 설정 값과 같은 정보가 들어있는 경우 정적 클래스를 사용한다.
Case 3) 객체 없이 전역적인 접근이 필요한 경우
static class GameManager
{
public static bool IsPaused;
}
GameManager.IsPaused = true;
- 위처럼 특정 객체를 찾아서 접근하지 않고 사용하는 경우가 있을 수 있다.
- 남용하지 않도록 주의해야 한다.
(4) 확장 메서드(Extension Method)
- 이런 것이 있다는 것 정도만 알고 있다. (이후, 다룰 때 정리해야 할 것 같다.)
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260506] C# ( 오버로딩 & 오버라이딩 차이점 ) (0) | 2026.05.06 |
|---|---|
| [20260506] C# (캡슐화, 상속, 다형성) (0) | 2026.05.06 |
| [C# 리마인드] 콘솔 스네이크 게임 만들기 (0) | 2026.05.03 |
| [C#] 콘솔 월남뽕 게임 만들기 (1) | 2026.05.01 |
| [20260430] C# 얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy) (0) | 2026.04.30 |