Unity

(Unity) C# 인터페이스(interface)

Janny_ 2022. 10. 11. 16:28

인터페이스(Interface)


인터페이스란 외부와 통신하는 공개 통로이며, 통로의 규격입니다. 인터페이스는 통로의 규격은 강제하지만 그 아래에 어떤 일이 일어날 지는 결정하지 않습니다.

C# 인터페이스는 어떤 메서드를 구현하도록 강제하는 계약이라고 볼 수 있습니다. 인터페이스를 상속하는 클래스는 해당 인터페이스의 메서드를 반드시 구현해야 합니다. 따라서 해당 인터페이스의 메서드를 구현했음이 보장됩니다.

 

인터페이스의 메서드는 선언만 존재하고 구현이 없습니다. 즉, 메서드 형태만 결정하고 메서드 구현 방법은 자신을 상속하는 클래스에 맡깁니다.

 

인터페이스를 상속한 클래스는 인터페이스에 선언된 메서드를 반드시 public으로 구현해야 합니다.


인터페이스 사용 예시

public interface IItem 
{
	void Use(GameObject target);
}

IItem의 Use() 메서드는 아이템을 사용하는 메서드입니다. 아이템을 사용할 대상을 GameObject 타입으로 입력받습니다.

 

IItem을 상속해서 만든 두 아이템 클래스는 다음와 같습니다.

public class AmmoPack : MonoBehaviour, IItem {
	public int ammo = 30;
    
    public void Use(GameObject target) {
    	//target에 탄알을 추가하는 처리
    	Debug.Log("탄알이 증가했다 : " + ammo);
    }
}

public class HealthPack : MonoBehaviour, IItem {
	public float health = 50;
    
    public void Use(GameObject target){
    	//target의 체력을 회복하는 처리
        Debug.Log("체력을 회복했다 : " + health)
    }
}

이와 같이 IItem을 상속한 클래스는 Use() 메서드를 반드시 구현해야 합니다. 단, Use() 메서드의 내부 구현은 클래스마다 달라도 상관없습니다. 따라서 Use() 메서드의 구현은 아이템의 역할에 따라 달라집니다.

 

어떤 스크립트에서 충돌한 아이템을 사용하는 처리를 구현한다고 가정할 때도 인터페이스의 사용은 효과적입니다.

void OnTriggerEnter(Collider other) {
	AmmoPack ammoPack = other.GetComponent<AmmoPack>();
    if (ammoPack != null)
    	ammoPack.Use();
	
    HealthPack healthPack = other.GetComponent<HealthPack>();
    if (healthPack != null)
    	healthPack.Use();
}

 

실제 게임에는 수백 개 아이템이 존재할 수 있습니다. 위와 같은 방식의 사용은 존재할 수 있는 수백 개 아이템의 타입을 전부 검사해야 합니다. 인터페이스를 사용한다면 다음과 같이 바꿀 수 있습니다.

void OnTriggerEnter(Collider other){
	IItem item = other.GetComponent<IItem>();
    if (item != null)
    	item.Use();
}

IItem 인터페이스를 상속한 클래스의 오브젝트는 IItem 타입으로 취급할 수 있습니다. GetComponent<IItem>()으로 가져온 컴포넌트의 실제 타입이 HealthPack이거나 AmmoPack일 수 있는데, IItem 타입을 상속하면 반드시 Use() 메서드를 가지고 있기 때문에 이는 중요하지 않습니다.

 

item.Use()가 실행될 때 item에 할당된 오브젝트가 HealthPack 타입이면 HealthPack의 Use()가 실행되고, AmmoPack 타입이면 AmmoPack의 Use()가 실행됩니다.

 

이처럼 인터페이스를 사용하는 방식은 '약속된 일'만 해준다면 세부 타입과 구체적인 구현을 따지지 않습니다.

인터페이스의 이러한 특징을 '느슨한 커플링'이라고 부릅니다. 느슨한 커플링은 어떤 코드가 특정 클래스의 구현에 결합되지 않아 유연하게 변경 가능한 상태를 가리키는 용어입니다.

 

 

 

 

 

 

 

 

 

 

<참고>

레트로의 유니티 게임 프로그래밍 에센스