객체지향의 OOP 마지막 특징으로 다형성을 알아보자.
class Player
{
protected int hp;
protected int attack;
public void Move()
{
Console.WriteLine("Player 이동");
}
}
class Knight : Player
{
public new void Move()
{
Console.WriteLine("Knight 이동");
}
}
class Mage : Player
{
public int hp;
public new void Move()
{
Console.WriteLine("Mage 이동");
}
}
class Archer: Player
{
public new void Move()
{
Console.WriteLine("Archer 이동");
}
}
class Program
{
static void EnterGame(Player player)
{
player.Move();
Mage mage = (player as Mage);
if ( mage != null)
{
mage.mp = 10;
}
}
static void Main(string[] args)
{
Knight knight = new Knight();
Mage mage = new Mage();
EnterGame(mage);
}
}
코드를 보고 설명하자면 EngterGame코드를 실행할때
player의 직업에 따라 Move함수를 호출하고 싶은데 저 코드를 실행해보면
이라고 나올 것이다.
우리가 원하는 값은 mage가 게임에 들어갔으니 Mage 이동을 원하는데
그렇다면 코드를 수정해보면,
{
Mage mage = (player as Mage);
if(mage != null)
{
mage.mp = 10;
mage.Move();
}
}
로 바꾸면 가능할 것이다. 근데, 직업이 늘어나면 늘어날수록 저런 조건문을 계속 추가한다면
그것은 너무 비효율적일 것이다.
그러므로, 지금 배울 문법이 있다.
class Player
{
protected int hp;
protected int attack;
public virtual void Move()
{
Console.WriteLine("Player 이동");
}
}
class Knight : Player
{
public override void Move()
{
Console.WriteLine("Knight 이동");
}
}
class Mage : Player
{
public int mp;
public override void Move()
{
Console.WriteLine("Mage 이동");
}
}
class Archer: Player
{
public override void Move()
{
Console.WriteLine("Archer 이동");
}
}
class Program
{
static void EnterGame(Player player)
{
player.Move();
Mage mage = (player as Mage);
if ( mage != null)
{
mage.mp = 10;
}
}
static void Main(string[] args)
{
Knight knight = new Knight();
Mage mage = new Mage();
EnterGame(mage);
}
}
또한, 상속받은 자식의 자식도 override를 쓰면 사용가능하다.
class Knight : Player
{
public override void Move()
{
Console.WriteLine("Knight 이동");
}
}
class SuperKnight : Knight
{
public override void Move()
{
Console.WriteLine("SuperKnight 이동");
}
}
또한, C#에서만 가능한 문법중에 더이상 자신의 자식은 override를 사용못하게 하는 sealed
이라는 문법도있다. (굳이 잘 사용하지않고 그냥 알고만 있자.)
class Knight : Player
{
public sealed override void Move()
{
Console.WriteLine("Knight 이동");
}
}
class SuperKnight : Knight
{
//override 재정의 사용불가
}
오버로딩 : 함수의 이름은 같고 인자만 다르게 사용하는 경우
오버라이딩 : 다형성을 이용하여 함수를 만드는 경우