| 다형성이란?
다형성(polymorphism)이란? 다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미한다.
즉, 다시말해 한가지 형태로 여러가지 작업을 할수 있다는 뜻이다. C#에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있다.
여기서 overide와 virtual로 다형성을 어떻게 구성하는지 집중적으로 탐구해 볼 것이다.
class Animal
{
public void sleep()
{
Debug.Log("동물이 자다");
}
}
class Monkey : Animal
{
public void sleep()
{
Debug.Log("원숭이가 자다");
}
}
public class TestScript : MonoBehaviour
{
Animal monkey = new Monkey();
void Start()
{
Debug.log(monkey.sleep());
}
}
이러한 스크립트가 있다고 하면, 출력은 부모클래스인 Animal의 "동물이 자다"가 출력된다.
하지만 Animal monkey = new Monkey();를 Monkey monkey = new Monkey();로 바꾸면 자식 클래스인 Monkey의 "원숭이가 자다"가 출력된다. 이유를 살펴보려면, 상속된 클래스가 호출될 때 메모리에 어떻게 올라오는지 알면 이해하기 쉽다.
|부모클래스와 자식클래스 호출 시 메모리 구조
메모리에는 Animal클래스만 호출하면 Animal클래스가 호출이되고, Monkey를 호출하면 자연스레 부모 클래스까지 호출이 된다. 따라서 Monkey를 호출하면 부모 클래스인 Animal클래스도 동시에 호출이돼서 Monkey호출로는 부모 클래스의 메소드와 자기자신의 메소드를 사용할 수 있다.
그런데 Animal monkey = new Monkey();는 Animal에 집중한다는 뜻이라서 부모 클래스의 메소드를 불러오고, Monkey monkey = new Monkey();는 자기 자신의 클래스에 집중한다는 뜻이라서 자기 자신의 메소드를 불러온다.
하지만 문제점은 Monkey뿐만 아니라 Tiger,Lion같은 동물 클래스도 있다면 어떻게 코드를 짜야할까?
class Animal
{
public void sleep()
{
Debug.Log("동물이 자다");
}
}
class Monkey : Animal
{
public void sleep()
{
Debug.Log("원숭이가 자다");
}
}
class Tiger : Animal
{
public void sleep()
{
Debug.Log("호랑이가 자다");
}
}
class Lion : Animal
{
public void sleep()
{
Debug.Log("사자가 자다");
}
}
public class TestScript : MonoBehaviour
{
Monkey monkey = new Monkey();
Tiger tiger = new Tiger();
Lion lion = new Lion();
List<Animal> animal = new List<Animal>();
void Start()
{
animal.Add(monkey);
animal.Add(tiger);
animal.Add(lion);
foreach(var i in animal)
{
i.sleep();
}
}
}
이런식으로 짜게 되면 "동물이 자다"가 세번 호출이 된다.
따라서 리스트 형식을 이용하지 못하고
monkey.sleep();
tiger.sleep();
lion.sleep();
이렇게 일일히 써줘야한다.
하지만 virtual과 overide를 사용한다면 이를 피할 수 있다.
(override와 virtual에 관한 설명)
C#, 클래스 개념 지식 : 오버로딩, 오버라이딩
| 오버로딩 오버로딩이란 함수명은 같지만 시그니쳐(매개변수 구성)를 달리해서 여러개의 함수를 사용할 수 있는 기법을 말한다. 만약 이런 기능이 없다면, 매번 다른 명의 함수명을 생각해내야
pdy0930.tistory.com
class Animal
{
public virtual void sleep()
{
Debug.Log("동물이 자다");
}
}
class Monkey : Animal
{
public override void sleep()
{
Debug.Log("원숭이가 자다");
}
}
이렇게 virtual과 override로 직접 쓴다는 것은 자식 클래스를 선언하면 자식클래스를 이용한다고 선언하는 것이나 마찬가지이다. 따라서 다음과 같이 코딩하면,
class Animal
{
public void sleep()
{
Debug.Log("동물이 자다");
}
}
class Monkey : Animal
{
public void sleep()
{
Debug.Log("원숭이가 자다");
}
}
class Tiger : Animal
{
public void sleep()
{
Debug.Log("호랑이가 자다");
}
}
class Lion : Animal
{
public void sleep()
{
Debug.Log("사자가 자다");
}
}
public class TestScript : MonoBehaviour
{
Animal monkey = new Monkey();
Animal tiger = new Tiger();
Animal lion = new Lion();
List<Animal> animal = new List<Animal>();
void Start()
{
animal.Add(monkey);
animal.Add(tiger);
animal.Add(lion);
foreach(var i in animal)
{
i.sleep();
}
}
}
"원숭이가 자다"
"호랑이가 자다"
"사자가 자다"
로 출력이 된다.
정리하자면 virtual과 override를 사용하면 코드 가독성도 좋아질 뿐더러, 반복문으로 한번에 표현하기도 쉽다.
'C#_ Unity Game programming' 카테고리의 다른 글
Unity, MVC와 MVP패턴의 차이점 및 실습 코드 (0) | 2024.01.05 |
---|---|
Unity, Scriptable Object개념 (1) | 2024.01.04 |
C# 인터페이스와 추상클래스 공통점과 차이점 (2) | 2024.01.02 |
C# 다형성과 업캐스팅 및 다운캐스팅 (0) | 2024.01.02 |
C#, 클래스 개념 지식 : 오버로딩, 오버라이딩 (0) | 2024.01.01 |