본문 바로가기
C#

C# 의 Interface 기초부터 활용까지

by Oz Driver 2025. 6. 26.

C#에서 인터페이스(Interface) 는 클래스가 따라야 할 규칙(계약서)을 정의합니다.
이번 편에서는 인터페이스에 대해 자세히 알아보겠습니다. 

 

인터페이스란?

인터페이스는 클래스나 구조체가 구현해야 할 기능만 정의하는 “타입” 입니다.

 

public interface IItem
{ 
    void Use(); 
}


•  이름 앞에 I 를 붙이는 것이 관례입니다. (IUsable, IDamageable 등)

  함수의 제목만 있고 구현은 없는 것이 특징입니다.

  앞에 public 을 붙이지 않으면 같은 파일 안에서만 보이게 됩니다. ( default 는 internal )

  다른 클래스나 다른 파일에서도 써야 하므로 명시적으로 public 을 붙여주는 것이 가독성 면에서 좋습니다.

 

상속? 구현?

문법적으로는 인터페이스도 : (콜론) 기호를 통해 클래스에 붙이기 때문에 상속 이라고도 표현할 수 있지만, 정확히는 구현(implement) 한다고 표현하는 것이 더 적절한 설명입니다. 

 

public class Potion : IItem
{     
    public void Use() 
    { 
        Console.WriteLine("아이템을 사용했습니다!"); 
    } 
}

 

• Potion은 IItem 의 기능을 상속받은 것이 아니라 직접 구현한 것입니다. 

따라서 인터페이스는 기능을 강제하는 일종의 약속 입니다. 

 

클래스와 인터페이스의 상속 관계

C# 에서는 클래스는 단일 상속만 가능하지만, 인터페이스는 여러 개 구현할 수 있습니다.

 

class Player : Character, IMovable, IAttackable
{
    // Character 클래스 상속 (1개만 가능)
    // IMovable, IAttackable 인터페이스 구현 (여러 개 가능)
}

 

class MyClass : A, B, C, ... 

의 형태가 있다고 가정면 A 는 class 이고 B, C, ... 는 Interface 입니다.

 

왜 인터페이스가 필요한가?

다양한 객체들이 동일한 함수를 가지고 서로 다른 방식으로 구현이 필요할 때 주로 사용하게 됩니다.

 

// GameObject class
public class GameObject
{
    public string Name { get; set; }
}

// IItem Interface
public interface IItem
{
    void Use();
}

// Potion Class
public class Potion : GameObject, IItem
{
    public Potion(string name) { Name = name; }
    
    public void Use() => Console.WriteLine($"{Name}을(를) 사용합니다");
}

// Sword Class
public class Sword : GameObject, IItem
{
    public Sword(string name) { Name = name; }
    
    public void Use() => Console.WriteLine($"{Name}을(를) 휘두릅니다");
}

 

 

인터페이스와 is, as

인터페이스도 클래스처럼 정식 타입입니다.
따라서 is타입 확인하거나, as로 안전하게 형변환할 수 있습니다. 

 

is 연산자 : 해당 타입인지 확인

GameObject gameObj = new Potion();

if (gameObj is IItem)
{
    Console.WriteLine("아이템입니다");
}

 

as 연산자 : 형변환 시도 (실패하면 null)

IItem item = gameObj as IItem;

if (item != null)
{
    item.Use();
}

 

is 연산자와 패턴 매칭을 함께 사용하여 타입 확인과 형변환을 동시에 ( C# 7.0부터 가능)

List<GameObject> objList = new List<GameObject> 
{ 
    new Potion("체력 포션"), 
    new Sword("강철 검"), 
    new Potion("마나 포션") 
}; 

foreach (var gameObj in objList) 
{ 
    Console.WriteLine($"이름 : {gameObj.Name}"); 
    
    if (gameObj is IItem item) 
    { 
        item.Use(); 
    } 
}

 

 is 연산자와 함께 변수 (item) 를 선언하면, 타입 검사와 동시에 형변환까지 할 수 있어 코드가 더 간결해집니다.

 

정리

  인터페이스는 기능만 정의하고, 실제 구현은 상속받은 클래스에서 합니다. 

  public 키워드를 명시해서, 외부 클래스에서도 사용할 수 있도록 선언하는 것이 좋습니다.

 클래스는 하나만 상속할 수 있지만, 인터페이스는 여러 개 구현할 수 있습니다.

  특히 is, as 를 사용하면, 인터페이스 기반의 객체 검사나 안전한 호출이 가능해집니다.