오늘은 간단하게 집고 넘어간다.
우리가 원하는것은 이것이다. Parent로 호출하는점이 편해서 Parent클래스로 호출했는데, 갑자기 child 클래스에 있는것들을 사용하고 싶었을 경우가 있을것이다. 이를 한번 살펴보자.
abstract class Entity
class Player : Entity
class Enemy : Entity
{
public void callEnemy()
{
ConsoleWriteLine("실행!");
}
}
자 우선 대충 다음과 같은 구조가 있다고 보자. Player와 Enemy 모두 Entity를 받기 때문에 여기서는 문제가 없는것 같다.
이와 같을 시 Main함수에서 다음과 같이 정의해주면 어떻게 될까?
Entity[] entityArray = new Entity[2] {new Player(), new Enemy()};
entityArray[1].callEnemy();
이와 같은 상황이 발생 시 두번째 줄에서 오류가 난다. 왜그럴까?
entityArray를 보면 Player와 Enemy를 Entity형식으로 받아왔다. 즉슨 실제 Enemy내부에 Enemy가 들어있어도, 우리가 가져온 정보는 Entity처럼 가져왔기 때문에, 그리고 Entity에는 해당 메서드가 없기때문에 오류가 난다. 이를 해결하기 위해 다음과 같은 방법을 쓴다.
if(entityArray[1] is Enemy)
{
Enemy e = entityArray[1] as Enemy;
e.callEnemy();
}
우선 if문에서 entityArray[1] 이 Enemy클래스를 따르는지 확인해준다. (당연히 Enemy를 생성해줬으므로 true를 반환할 것이다.) 이때 사용하는 "param is ClassT" 이 "is"라는것을 활용하여 작업해 줄 수 있다.
그렇다고 하더라도, 바로 메소드를 호출 할 수 있는것은 아니다. 이를 Enemy형식에 맞게 바꿔주어야 한다. 다음 코드를 보면 Enemy e 를 새로 정의해주고 (이건 Enemy가 확실하다) entityArray[1] as Enemy를 불러준다. 이는 entityArray[1]을 Enemy클래스 형식에 맞게 바꾸어 준다.
이제 남은일은 Enemy인 e의 메소드를 호출하는 것 뿐이다.
물론 Enemy인것이 맞지만, 보통 if문에 is를 통해 타입 확인을 해 주는것이 좋다.
같은 예제로 다음을 보자.
abstract class Entity
{
virtual void Attack()
{
Console.WriteLine("공격한다");
//Do A
//Do B
//...
}
}
class Player : Entity
{
override void Attack()
{
Console.WriteLine("공격한다");
//Do A
//Do B
//...
this.atk++;
}
}
class Enemy : Entity
자 다음과 같이 Entity에 Attack이라는 매소드가 있다. 이는 공격한다를 출력하고 후속 조치를 하며, virtual로 선언하여 override가능하다.
이제 플레이어를 보면 같은 Attack을 오버라이딩 하였다. 문제는 Entity에 해당되는 내용이 Attack에도 거의 똑같이 적용되고있다. 그리고 이제 atk를 올려주는 작업 단 하나만이 추가되어있다.
지금 네줄로 퉁쳤지만, 이게 엄청나게 많은 코드를 그대로 overriding할 필요가 있는가를 생각해보면, 전혀 그렇지 않다. (쓰기도 귀찮고 보기도 안좋고 실수도 가능하고...)
이럴때 사용하는것이 base이다. 다음 예제를 보자.
abstract class Entity
{
virtual void Attack()
{
Console.WriteLine("공격한다");
//Do A
//Do B
//...
}
}
class Player : Entity
{
override void Attack()
{
base.Attack();
this.atk++;
}
}
class Enemy : Entity
자 우리는 base.Attack()이라는 것을 사용하였다. 이것이 무엇인지 알아보면, base, 즉 Parent에 있는 Attack메소드를 그대로 가져와서 사용하겠다는 것이다. 이를 확인해보면 실수도 있을일 없고, 보기도 훨씬 간결해졌다.
물론 파라미터가 있다면 같이 넣어줘서 작업하면 결국엔 같다.
그 후 내가 이 override시 하고 싶은 행위들을 앞, 혹은 뒤에 넣어주면 끝이다.