본문 바로가기

교육 노트/C# 강의

[C# 때려잡기] C# 강의 30. 다형성, 다운 캐스팅 업 캐스팅

기존에 내 캐릭터에 칼을 가지도록 하였다.


class Weapon
{
public void Attack()
{
Console.WriteLine("무기로 공격!");
}
}
class Knife : Weapon
{
public void Attack()
{
Console.WriteLine("칼로 공격!");
}
}
class Gun : Weapon
{

}
class Bow : Weapon
{

}

class Character
{
private Knife k;
private Gun g;
private Bow b;
//...

}

아근데 칼만 쓸것은 아니니까

총도 넣고 활도 넣고 지팡이도넣고...

와 그러면 character는 맴버변수로 게임에쓰이는 모든 무기를 다 가지고 있어야한다.

메모리를 미친듯이 잡아먹는다.


공격할때마다 if문 으로 어떤무기인지 검사하고 해당 무기를 써줘야한다

미친듯이 느려진다.


해결방안을 알아보기전에


캐스팅에대하여 알아보자



1. 캐스팅

int를 float로 float를 int로 ... 과 같은 것을 캐스팅이라고 했다.


그렇다면 우리가 만든 클래스를 다른 클래스로 바꾸는것이 가능할까?



Gun/ Knife / Bow를 weapon으로 바꾸면 위로가는 캐스팅이라고 하여 업 캐스팅 (up casting) 이다.


반대로



weapon을 gun/knife/bow로 바꾼다면 그것은 위에서 아래로 바꾸는 캐스팅이므로 다운 캐스팅 (down casting) 이다.


일반적으로 부모를 통하여 
자식 객체에 접근하는 (업 캐스팅) 은 허용되지만
자식으로 부모객체를 가르키는경우는
 허용되지않는다.



자식객체가 만들어질때 부모 객체도 만들어진다고 했었는데.

따라서 자식객체는 부모객체를 포함하고 있는 사이즈를 가지고있다.

따라서 자식 객체 포인터라면 컴파일러가

아 이 포인터를 따라가면 요기부터 요기까지가 이놈이 차지하는 공간이것구나~ 하고 생각하는데

자식 포인터가 부모 객체를 가르키면

아 요기부터 요기까지가 이놈 공간이라고 생각하고 사용하려는데

그공간에는 아무것도 안들어있는 경우가 생긴다.

Bow b; 라고 선언되었어서

b.setReach(5); 뭐 이런식으로 썻는데 거기있는 객체가 bow가 아니라 weapon이어 가지고 setReach 함수도 없고 reach 변수도 없으면 

다운캐스팅은 강제로 했다한들 저 뒤에 메모리공간을 그냥 강제로 사용하는것이다. 저기에 어떤 메모리가 있었는지도 모르지만 강제로 사용 불가능해야 하는 메모리를 써버리는것이라 프로그램에 어떤 문제가 발생할지 조차 모르는것이다.



뭐 암튼 부모객체로 자식객체를 가르킬수있다는것이다.


자 지금까지 부모와 자식간의 캐스팅 방법을 알아보았다.

근데 부모 자식간에 바꿔서 어디서 쓰냐고?



2, 다형성


class Character
{
private Weapon w;

public Character()
{
w = new Gun();
}

}


방금 업캐스팅은 된다고 했다. 즉 부모로 자식 객체는 가르킬수 있으니 부모를 만들고 이를 이용하여 그때그때 원하는 자식 객체를 만들어(동적할당) 하여 그 객체를 가르키게 하면 된다.

위에서는 Weapon을 이용하여 Gun을 만들어 사용하고있다.



이렇게 부모 하나로 다양한 클래스를 만들고 가르킬수있다.

이런것을 다형성이라고 한다.


또한 자식 객체에만 있는 함수를 부르고싶을때는

그때만 다운캐스팅 하여 호출하면된다

w = new Gun();
((Gun)w).Reload();


728x90