본문 바로가기

[내배캠] 본 캠프 개발 학습/자세히 살펴보는 Q&A

C# 동적 인스턴스 생성

  • 단축키

    - F12: 현재 커서 위치의 변수, 메소드, 클래스 또는 속성의 정의된 위치로 이동  
    - F9:  현재 커서가 위치한 줄에 중단점을 추가하거나 제거, 중단점은 디버깅 중 특정 줄에서 실행을 일시 중지

  • Console.ReadKey();
 while (true)
 {
    // 생략

     if (input == "0")
     {
         Location.SetLocation(STATE.마을);
         break;
     }
     else if (input == "1")
     {
         Random random = new Random();

         player.HP += random.Next(0, 51);
         player.MP += random.Next(0, 51);

         Console.WriteLine("회복을 완료했습니다.");
         
         break;
     }

     else { Console.WriteLine("잘못된 입력입니다."); }
     Location.SetLocation(STATE.마을);
 }

 Location.SetLocation(STATE.마을);

 MyLog.절취선();

 

 실행 했을 때 "회복을 완료했습니다" 메세지가 출력되지 않는 것처럼 보이지만, 실제로 코드는 실행되었고 메세지도 출력되었으나 바로 break; 가 걸리면서 마을로 가기 때문에 메세지를 보지 못 하는 것임. 

  Console.WriteLine("회복을 완료했습니다.");
  Console.ReadKey();

  break;

 

Readkey 함수를 사용해 break가 바로 걸리지 않게 수정함.  

 

  • 필드 변수를 캡슐화 해서 다른 클래스로 가져가기

    * 캡슐화 방법은 9/30 TIL 참고 
public class MiniGame
{
 private int getgold;
 
 public int GetGold()
 {
     return getgold;
 }
 
 public class Player
{
   public Inventory inventory;
   public MiniGame minigame;

   public Player()
   {
       inventory = new Inventory(this);
       minigame = new MiniGame(this);  
   }

 

 미니게임 클래스의 변수를 플레이어 클래스에서 참조하기 위해 인스턴스를 만든 상황. 

public void DisplayStatus()
{
        // 생략
        $"Gold : {gold + getgold} G\r\n\r\n" +

        "0. 나가기\r\n\r\n" +

        "원하시는 행동을 입력해주세요.\r\n" +
        ">>";

    Console.WriteLine(text);


왜 위의 코드처럼 변수 "getgold"를 플레이어 클래스의 메서드에서 바로 참조할 수 없는 걸까? 

기존에는 인스턴스의 개념을 정확히 이해하지 못 해서 인스턴스를 생성해 클래스를 참조하면 해당 클래스 내의 변수와 함수를 마음대로 불러올 수 있는 줄 알았다. 

코드를 하나씩 살펴보면서 개념을 이해해보자. 

public class MiniGame
{
 private int getgold;
 
 public int GetGold()
 {
     return getgold;
 }


private 로 선언된 함수를 외부에서 읽을 수 있도록 public 함수로 바꿔준다. 이때 GetGold는 getgold라는 변수값을 가지고 있다. 

public class Player
{
   public MiniGame minigame;


플레이어 클래스 필드에서 미니게임 클래스를 불러온다. 
이때 주의할 점: 클래스를 생성한 게 아니라 클래스의 틀만 가져온 것!
붕어빵을 만드는 틀이라고 생각하면 쉽다. 붕어빵 틀 안에 어떤 게 있는지 알 수 없는 상태이다.  

 public Player()
   {
       minigame = new MiniGame(this);  
   }

 

생성자 함수를 통해 인스턴스를 생성한다. 
지금은 필드에서 선언한 붕어빵 틀을 사용해 붕어빵을 만든 상태이다. 

이제 미니게임 클래스에서 public으로 선언한 함수를 읽을 수 있게 된다. 

public void DisplayStatus()
{
        // 생략
        $"Gold : {gold + minigame.GetGold()} G\r\n\r\n" +

        "0. 나가기\r\n\r\n" +

        "원하시는 행동을 입력해주세요.\r\n" +
        ">>";

    Console.WriteLine(text);


이 과정을 거치면 플레이어 클래스에서 "minigame.GetGold()" 입력값으로 함수를 참조할 수 있게 된다.

정리하면, (클래스의 객체인)minigame.(public 으로 읽을 수 있게 선언된)GetGold 함수. 
플레이어 클래스는 GetGold가 어디에서 왔는지 모르기 때문에 객체까지 참조해야 한다. 

 

  • 추가

    원본 클래스와 그 클래스의 인스턴스(객체)는 다르다.
    B 클래스에서 생성한 A 클래스의 인스턴스와  C 클래스에서 생성한 A가 클래스의 인스턴스가 다르다는 의미이기도 하다.
    하지만 하나의 클래스에서 여러 개의 인스턴스를 생성할 경우 코드가 꼬이거나 메모리 문제가 발생한다. 이때 사용하는 싱글톤은 딱 하나의 인스턴스만 만드는 것으로,  여러 클래스에서 동일한 인스턴스를 공유해야 할 때 싱글톤 패턴을 사용한다.