전체 코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;

namespace CSharp
{

    // 다형성
    // 클래스 형식 변환
    // 
    class Player
    {
        protected int hp;
        protected int attack;
    }

    class Knight : Player
    {

    }

    class Mage : Player
    {
        public int mp;
    }
    internal class Program
    {
        static void EnterGame(Player player)
        {
            // 기본적인 방법
            // 타입을 체크하는 문법이 있어야 정상
            // 체크하는 문법은\

            // is키워드
            bool isMage = (player is Mage);
            if (isMage)
            {
                //Mage mage = (Mage)player;
                //

            }

            // as키워드
            Mage mage = (player as Mage);
            if (mage != null)
            {
                mage.mp = 10;
            }
            // null :
            // 없음이란 의미랑 같다.
            // 참조하는 것이 없음
            //

        }

        static Player FindPlayerById(int id)
        {
            // 해당 플레이어 찾으면 
            // ~
            // 못찾으면 null return
            return null;
        }

        static void Main(string[] args)
        {
            // 스택에서는 메모리 주소를 참조하고 -> 실제 데이터는 힙메모리에 생김
            Knight knight = new Knight();  

            Mage mage = new Mage();

            // Mage 타입은 Player 타입으로 변경 가능
            // 모든 Player타입은 Mage 타입이 안됨 따라서 안심을 시켜줘야함
            Player magePlayer = mage;
            // 강제로 할 때의 문제점은 mage가 아닌 Knight를 변환 했었을 경우
            // 에도 문법적인 문제가 되지 않음
            // 런타임 에러가 발생함

            // 컴파일단계에서 에러를 뱉어주면 좋겠지만
            // 실행전까지는 어떻게 되는지 문법적으로 알 가능성이 없음
            // 

            Mage mage2 = (Mage)magePlayer;


            Player p1 = knight;
            Mage m1 = (Mage)p1;
            EnterGame(knight);
            EnterGame(mage);

            Knight Knight2 = null;

        }

    }
}

1. 클래스 형식 변환이란?

클래스 형식 변환(Type Casting)이란 부모 클래스와 자식 클래스 간의 형 변환을 수행하는 과정을 의미합니다.
C#에서는 업캐스팅(Upcasting)다운캐스팅(Downcasting)을 사용할 수 있으며, 이를 통해 다형성을 효과적으로 활용할 수 있습니다.

2. 업캐스팅(Upcasting)

자식 클래스 → 부모 클래스로 변환하는 것.

업캐스팅은 항상 자동으로 수행되며, 안전한 변환입니다. 즉, 자식 클래스의 객체를 부모 클래스 타입의 변수에 할당할 수 있습니다.

📝 예제 코드 (업캐스팅)

class Player
{
    public int hp;
    public int attack;
}

class Knight : Player
{
    public void Move() { Console.WriteLine("Knight Move"); }
}

class Mage : Player
{
    public void CastSpell() { Console.WriteLine("Mage Casts Spell"); }
}

class Program
{
    static void Main(string[] args)
    {
        Knight knight = new Knight();
        Player player = knight; // ✅ 업캐스팅: 자식 타입을 부모 타입으로 변환

        player.hp = 100; // ✅ 부모 클래스의 멤버 접근 가능
        // player.Move(); // ❌ 컴파일 에러: 부모 타입 변수로는 자식의 멤버 접근 불가능
    }
}

🔹 업캐스팅 특징

  • 자동 변환: Knight 타입의 객체를 Player 타입 변수에 할당할 때 명시적인 형변환이 필요 없음.
  • 부모 클래스 멤버만 접근 가능: playerKnight 객체를 참조하지만, Move()는 호출할 수 없음.

3. 다운캐스팅(Downcasting)

부모 클래스 → 자식 클래스로 변환하는 것.

다운캐스팅은 자동으로 수행되지 않으며, 명시적인 형변환이 필요합니다. 또한, 잘못된 다운캐스팅은 런타임 오류(InvalidCastException)를 발생시킬 수 있습니다.

📝 예제 코드 (다운캐스팅)

class Program
{
    static void Main(string[] args)
    {
        Player player = new Knight(); // 업캐스팅
        // Knight knight = player; // ❌ 컴파일 에러!
        Knight knight = (Knight)player; // ✅ 명시적 형변환 필요
        knight.Move(); // ✅ 정상 동작
    }
}

🔹 다운캐스팅 특징

  • 명시적 형변환 필요: (Knight)player처럼 직접 변환을 지정해야 함.
  • 런타임 오류 가능성: Player 변수가 Knight 객체를 참조하고 있지 않다면 변환 시 오류 발생.

4. 안전한 다운캐스팅 방법

다운캐스팅 시 런타임 오류를 방지하기 위해 is 연산자as 연산자를 사용할 수 있습니다.

🔹 is 연산자 사용

Player player = new Knight();
if (player is Knight)
{
    Knight knight = (Knight)player;
    knight.Move(); // ✅ 안전한 캐스팅
}
  • is 연산자는 객체가 특정 타입인지 확인한 후 변환을 수행하므로, 런타임 오류를 방지할 수 있음.

🔹 as 연산자 사용

Player player = new Mage();
Mage mage = player as Mage;
if (mage != null)
{
    mage.CastSpell(); // ✅ 안전한 캐스팅
}
  • as 연산자는 형변환이 불가능할 경우 null을 반환하여 예외 발생을 방지함.

5. 잘못된 다운캐스팅 예제

Player player = new Knight();
Mage mage = (Mage)player; // ❌ 런타임 오류 발생!
  • playerKnight 객체를 참조하고 있으므로 Mage로 변환 불가능 → InvalidCastException 발생.
profile
李家네_공부방

0개의 댓글