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;
}
}
}
클래스 형식 변환(Type Casting)이란 부모 클래스와 자식 클래스 간의 형 변환을 수행하는 과정을 의미합니다.
C#에서는 업캐스팅(Upcasting)과 다운캐스팅(Downcasting)을 사용할 수 있으며, 이를 통해 다형성을 효과적으로 활용할 수 있습니다.
자식 클래스 → 부모 클래스로 변환하는 것.
업캐스팅은 항상 자동으로 수행되며, 안전한 변환입니다. 즉, 자식 클래스의 객체를 부모 클래스 타입의 변수에 할당할 수 있습니다.
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 타입 변수에 할당할 때 명시적인 형변환이 필요 없음.player는 Knight 객체를 참조하지만, Move()는 호출할 수 없음.부모 클래스 → 자식 클래스로 변환하는 것.
다운캐스팅은 자동으로 수행되지 않으며, 명시적인 형변환이 필요합니다. 또한, 잘못된 다운캐스팅은 런타임 오류(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 객체를 참조하고 있지 않다면 변환 시 오류 발생.다운캐스팅 시 런타임 오류를 방지하기 위해 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을 반환하여 예외 발생을 방지함.Player player = new Knight();
Mage mage = (Mage)player; // ❌ 런타임 오류 발생!
player는 Knight 객체를 참조하고 있으므로 Mage로 변환 불가능 → InvalidCastException 발생.