[C#] Interface - 인터페이스

PIAZZI·2024년 4월 26일

C#

목록 보기
5/9
post-thumbnail

Interface - 인터페이스

  • 메소드의 목록만 미리 정해놓은 것
  • 추상 클래스와 비슷한 점이 있는데, 메소드의 목록만 선언하고 구현은 하지 않기 때문이다.
  • 인터페이스의 이름을 정할 때는 클래스와의 구분을 위해 앞에 대문자 I를 쓰는 관례가 있다.
  • 다른 인터페이스로부터 상속이 가능하다.

간단하게 말하자면 사용할 메소드들을 모아둔 명세라고 할 수 있다.


형태

다음은 인터페이스의 선언 형태이다.
interface 키워드를 사용한다.

접근_지정자 interface 이름
{
}

다음은 선언한 인터페이스를 상속받는 클래스의 형태이다.

접근_지정자 calss 자식_클래스_이름 : 인터페이스
{
}

예시를 들면 다음과 같다.


public interface IUnit{ 	//Attack()과 Move() 메소드가 들어가 있다.
    void Attack();
    void Move();
}

public class Goblin : IUnit // IUnit 인터페이스를 상속 받았다.
{
	public void Attack() 	// IUnit 인터페이스의 Attack 메소드를 구현하였다.
    {
    	Console.WriteLine("고블린의 공격") 
    }
    
    public void Move()
    {
    	Console.WriteLine("고블린의 이동") 	// IUnit 인터페이스의 Move 메소드를 구현하였다.
    }
}

public class Ghoul : IUnit
{
	public void Attack()
    {
    	Console.WriteLine("구울의 공격")
    }
    
    public void Move()
    {
    	Console.WriteLine("구울의 이동")
    }
}

static void main(string[] args)
{
	Goblin goblin = new Goblin();
    goblin.Attack();
    goblin.Move();
    
    Ghoul ghoul = new Ghoul();
    ghoul.Attack();
    ghoul.Move();
}

interface IUnit에서 Attack(), Move() 메소드를 명세만 하고, 자식 클래스에서 각자 구현한 것을 볼 수 있다.

여기까지만 보면 추상 클래스비슷하게 보인다.
그래서 추상 클래스인터페이스를 비교해보려 한다.

우선 둘의 공통점은 다음과 같다.

  • 추상 메소드를 가지고 있다 - 선언만 있고 구현 내용이 없음.
  • 객체를 생성할 수 없다.
  • 가지고 있는 추상 메소드는 반드시 자식 클래스에서 기능 구현을 해야한다.

차이점은 다음과 같다.

  • 추상 클래스는 선택적으로 추상 메소드를 가질 수 있는 반면에, 인터페이스는 전부 추상 메소드만 가진다.
  • 클래스는 다중 상속이 되지 않는다. 하지만 인터페이스는 다중 상속이 가능하다.

차이점에서 볼 수 있듯이, 인터페이스는 오직 추상 메소드만을 가진다.

추상 클래스는 정상 메소드와 일부 추상 메소드가 있을 수 있다.
허나 인터페이스는 오직 추상 메소드만을 가진다.

사용 목적에 따라 추상 클래스를 사용할지, 인터페이스를 사용할지 나뉜다고 보면 된다.

추상 클래스 - 개념의 확장

  • 상속받는 클래스들에게 동일한 추상 메소드를 주고 각각의 자식 클래스에서 새로 재정의한다.
    그리고 추가로 고유의 메소드들을 만들 수 있다.

    (주어진 추상 메소드의 목적은 동일하고, 기능만 각각의 자식 클래스마다 다를 뿐이다.)
    (또한 추가로 자식 클래스에서 새로 메소드를 만들어서 고유의 기능을 만들 수 있다.)

이러한 점이 개념의 확장이라고 말 할 수 있다면, 인터페이스는 다른 점이 있다.

인터페이스 - 기능의 명세

  • 공통적인 메소드를 받아 구현한다는 것은 동일하다.
    허나 추가로 고유의 메소드를 만들 수는 없고, 오직 상속받은 추상 메소드만 사용가능하다.
    즉 기능을 추가하여 확장을 하기 보다는, 동일한 개념들의 기능들을 새롭게 구현하는 것에 초점을 둔다.

상속받은 추상 메소드를 집중적으로 구현하는 것을 목적으로 둔다고 볼 수 있다.
위에서 설명한 공통적인 기능의 명세처럼 정말 사용할 메소드들만 나열해둔 것이다.

스마트폰 기본 기능을 클래스로 구현했다고 생각해보자

abstract class 스마트폰_기본_기능
{
	통화_기능();     //메소드
    메세지_기능();   //메소드
    블루투스_기능(); //추상 메소드 
}

class S회사_스마트폰 : 스마트폰_기본_기능
{
	통화_기능()    // 메소드
    메세지_기능()  // 메소드
    블루투스_기능() // 메소드
}

블루투스 기능추상 메소드로 선언했다.
그래서 S회사 스마트폰 클래스에서는 반드시 자신들만의 블루투스 기능구현해야한다.
또한 S회사 스마트폰만의 기능구현하기 위해 메소드를 추가할 수 있다.

그럼 인터페이스를 사용하면 어떻게 될까?

interface 통화_기능
{
}

interface 메세지_기능
{
}

interface 블루투스_기능
{
}

class A회사_스마트폰 : 통화_기능, 메세지_기능, 블루투스_기능 // 인터페이스는 다중 상속이 된다고 했는데, 바로 이것이다!
{
	통화_기능 구현
    메세지_기능 구현
    블루투스_기능
}

만일 A회사에서 블루투스 기능을 구현할 생각이 없다면 블루투스 기능 인터페이스를 받지 않으면 된다!

추상 클래스와 달리 인터페이스는 필요한 기능의 명세라는 점을 볼 수 있다.


개인적인 공부를 위해 정리한 내용이며, 틀린 점이 있을 수 있습니다.
만일 틀린 내용이 있다면, 댓글로 알려주시면 감사하겠습니다.

profile
범부에오

0개의 댓글