1. virtual을 사용하는 이유
Monster 클래스를 상속 받은 Slime이라는 클래스가 있습니다.
Slime 클래스는 슬라임의 종족 특성으로 기존 몬스터 이동속도에서 추가 되야하는 이동속도 값이 존재합니다.
이를 위해 Slime의 GetMoveSpeed라는 프로퍼티를 구현해서 추가 이동속도 값을 더해서 값을 반환해줬습니다.
이후 slime 객체에서 Move()를 실행하게 되는데 문제는 여기서 발생합니다.
슬라임의 이동속도를 더하는 GetMoveSpeed를 만들었지만 사용되지 않았습니다.
이는 Move()안의 매개변수 Monster가 다형성이기 때문입니다.
Monster는 Monster 클래스를 가리키지만 동시의 Monster 클래스를 상속 받은 Slime이 될 수도 있습니다.
따라서 위 코드의 _monster.name은 slime의 이름, _monster.GetMoveSpeed는 Monster 프로퍼티를
가리키게 된 것입니다. 이후 더 많은 몬스터들을 만들게 되면 종류는 매우 다양해집니다.
이를 해결하기 위해 위처럼 Move 함수를 오버로딩하여 매개변수 타입만 변경해서 해결할 수 있지만,
계속해서 새로운 객체들이 생겨나면 그때마다 수정을 해야하고 만들어야하며 상속 받은 친구들은
사용하지도 않는 데이터들을 포함하게 되어, 메모리 적으로도 좋지 않습니다.
이는 객체지향 언어에서 추구하는 바가 아닙니다.
이를 해결하기 위해 사용하는 것이 가상매서드 virtual과 override입니다.
2. virtual 사용방법
virtual의 뜻은 쉽게말해 재정의 할 수 있다, 혹은 재구현 할 수 있다 정도로 생각해주면 됩니다.
override는 virtual로 된 것을 재정의하겠다, 혹은 재구현 하겠다는 의미입니다.
한마디로, 부모에서 만든 GetMoveSpeed를 자식에서 재정의해서 사용한것입니다.
이를 이용하면 부모 클래스에서 만들어 놓은 기능들을 자식 클래스에서 상속받아
그 값을 원하는대로 수정하여 재구현할 수 있습니다.
객체 지향언어에서는 객체를 찍어내는 부모 Class는 항상 간결하고 구현하고자 하는 바가 명확하며,
그 값이 수정되지 않는 것이 좋습니다.
우리가 붕어빵을 찍어내는 틀을 식상하다고 변형시켜 새로운 붕어빵틀로 만들게 되면 더 이상 원래 기본이 되는
붕어빵을 만들 수 없게 됩니다. 왕관을 쓰고있는 붕어빵을 만들고 싶다면, 기존틀은 냅두고 기존걸 토대로 원하는 부분만
추가하여 새로운 틀을 만들면 되는 것처럼 클래스도 같습니다. 최대한 기본이 되는 부모클래스는 유지하고,
이후 만들어진 객체는 부모클래스를 이어 받은 자식들마다 새롭게 구성해주는 방향이 맞다고 생각합니다.
- 예제 코드
namespace ConsoleApp7
{
internal class Program
{
public class Monster
{
protected string name = "None";
protected float attack = 10f;
protected float moveSpeed = 5f;
public Monster() { }
public Monster(string _name)
{
name = _name;
}
//Monster의 Move Speed값
virtual public float GetMoveSpeed
{
get { return moveSpeed; }
}
public void Move(Monster _monster)
{
Console.Write("{0}이 {1}의 속도로 이동했습니다.", _monster.name, _monster.GetMoveSpeed);
}
}
public class Slime : Monster
{
//슬라임의 추가 이동속도
float addSpeed = 5f;
//슬라임의 MoveSpeed값
override public float GetMoveSpeed
{
get { return moveSpeed + addSpeed; }
}
public Slime(string _name)
{
name = _name;
}
}
static void Main(string[] args)
{
Slime slime = new Slime("슬라임");
slime.Move(slime);
}
}
}
'C#' 카테고리의 다른 글
C# BlackJack (1) | 2024.01.08 |
---|---|
C# SnakeGame (1) | 2024.01.06 |
C# Partial (2) | 2024.01.05 |
C# Static (2) | 2024.01.04 |
C# Class (0) | 2024.01.04 |