08.클래스 형식 변환 — 웹툰PD 지망생 : 정민재
08.클래스 형식 변환
카테고리 없음

08.클래스 형식 변환

728x90

 

비효율 - 매개변수의 각개전투(부모 없이 자식들 끼리 따로따로 나서는 경우)

using System;

namespace Csharp
{    
    class Player                         //부모
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player                //자식
    {

    }

    class Mage : Player                  //자식
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Knight knight)
        {
            //비효율의 극치 - 이런식으로 하면 나중에 캐릭터가 100개가 넘어가면?
        }

        static void EnterGame(Mage mage)
        {
            //비효율의 극치 - 이런식으로 하면 나중에 캐릭터가 100개가 넘어가면?
        }

        static void Main(string[] args)
        {
            //Knight knight (스택)
            //new Knight(); (힙)
            Knight knight = new Knight();

            Mage mage = new Mage();
        }
    }
}

 

효율 - 매개변수 통합(부모가 대표로 나서서 통합)

using System;

namespace Csharp
{    
    class Player                               //부모
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player                      //자식
    {

    }

    class Mage : Player                        //자식
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)
        {
                                                //1
        }


        static void Main(string[] args)
        {
            //Knight knight (스택)
            //new Knight(); (힙)
            Knight knight = new Knight();

            Mage mage = new Mage();


            EnterGame(knight);                  //2
            
            EnterGame(mage);                    //2
        }
    }
}

 

static void EnterGame(Player player) 이 코드 한 줄로 인해

 

수백줄의 코드를 줄여버렸다.

 

그리고나서 Main함수에서는 신기하게도

 

EnterGame(knight), EnterGame(mage)로 받고 있다. 

 

 

클래스 형변환

using System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)
        {
            //Mage의 mp변수를 어떻게 가져올 것인가? ----> 형변환을 이용
        }


        static void Main(string[] args)
        {
            //Knight knight (스택)
            //new Knight(); (힙)
            Knight knight = new Knight();

            Mage mage = new Mage();


            EnterGame(knight);
            
            EnterGame(mage);
        }
    }
}

 

 

using System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)
        {
            //Mage의 mp변수를 어떻게 가져올 것인가? ----> 형변환을 이용
        }


        static void Main(string[] args)
        {
            //Knight knight (스택)
            //new Knight(); (힙)
            Knight knight = new Knight();

            Mage mage = new Mage();

            //만약 어떤 변수가 Mage 타입 -> 이 변수는 Player타입으로 변환할 수 있을까? 있다. 왜? 모든 Mage는 Player이기 때문에
            //만약 어떤 변수가 Player 타입 -> 이 변수는 Mage타입으로 변환할 수 있을까? 없다. 왜? Player가 아니라 Knight 타입에서 변환된 것일수도 있으므로
            Player magePlayer = mage;
            Mage mage2 = magePlayer;    //빨간줄

            EnterGame(knight);            
            EnterGame(mage);
        }
    }
}

 

 

조용히 프로그램이 터지는 상황

using System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)
        {
            //Main함수에서 EnterGame(knight)로 인해 static void EnterGame(Player player)에서 player가 knight를 받은 상태에서
            //player는 knight인 상태인데, 또 다시 (Mage)player로 형변환을 해서 프로그램이 터짐            
            Mage mage = (Mage)player;	//여기서 프로그램 터짐

            //mp도 접근할 수 있음
            mage.mp = 10;
        }


        static void Main(string[] args)
        {
            //Knight knight (스택)
            //new Knight(); (힙)
            Knight knight = new Knight();

            Mage mage = new Mage();

            //만약 어떤 변수가 Mage 타입 -> 이 변수는 Player타입으로 변환할 수 있을까? 있다. 왜? 모든 Mage는 Player이기 때문에
            //만약 어떤 변수가 Player 타입 -> 이 변수는 Mage타입으로 변환할 수 있을까? 없다. 왜? Player가 아니라 Knight 타입에서 변환된 것일수도 있으므로
            Player magePlayer = mage;

            //강제로 형변환
            //하지만 magePlayer가 Mage가 아니라 knight였으면...?
            Mage mage2 = (Mage)magePlayer;  

            EnterGame(knight);
        }
    }
}

 

부모player가 자식knight 타입인지? 자식 mage타입인지? 질문하는법(첫 번째 방법 - is)

using System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)    //EnterGame(knight)로 인해 player는 현재 knight타입
        {
            //부모player는 어떤 타입일까? 자식knight 타입인지? 자식 mage타입인지? 질문하는법
            bool isMage = (player is Mage);
            if(isMage)
            {
                Mage mage = (Mage)player;
                mage.mp = 10;
            }
            //이렇게 하면 프로그램이 뻗지 않는다.
        }


        static void Main(string[] args)
        {
            Knight knight = new Knight();

            Mage mage = new Mage();

            //player 매개변수에 knight타입을 집어넣음
            EnterGame(knight);
        }
    }
}

 

부모player가 자식knight 타입인지? 자식 mage타입인지? 질문하는법(두 번째 방법 - as)

using System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }

    class Program
    {
        static void EnterGame(Player player)    //EnterGame(knight)로 인해 player는 현재 knight타입
        {
            //부모player는 어떤 타입일까? 자식knight 타입인지? 자식 mage타입인지? 질문하는법
            //player as Mage에서 Mage가 아니라 knight이면 null이 뜬다
            Mage mage = (player as Mage);

            //만약 mage가 null이면 실행 안하고 (= player는 knight)
            //만약 mage가 null이 아니면 실행 (= player는 mage)
            if (mage != null)
            {               
                mage.mp = 10;
            }
            //이렇게 하면 프로그램이 뻗지 않는다.
        }


        static void Main(string[] args)
        {
            Knight knight = new Knight();

            Mage mage = new Mage();

            //player 매개변수에 knight타입을 집어넣음
            EnterGame(knight);
        }
    }
}

 

 

player매개변수를 mage가 아닌 knight로 바꿔보았을 때

 

 

null

sing System;

namespace Csharp
{    
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Program
    {
        static Player FindPlayerById(int id)
        {
            //id에 해당하는 플레이어를 탐색

            //못찾았으면 
            return null;
        }
    }
}

 

그리고 null의 뜻은

 

'없음', '내가 참조하는 타입이 아무것도 가리키지 않는다'

728x90