Notice
Recent Posts
Recent Comments
Link
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

I'm FanJae.

[20260504] C# (프로퍼티, 생성자, 메서드 II) 본문

Unity/Unity 초격차캠프

[20260504] C# (프로퍼티, 생성자, 메서드 II)

FanJae 2026. 5. 4. 17:28

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);

MaxSystem.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)

- 이런 것이 있다는 것 정도만 알고 있다. (이후, 다룰 때 정리해야 할 것 같다.)

 
Comments