728x90
반응형

실무에서 interface 를 기반으로 설계하기란, 여간 번거로운게 아니다.

DI Pattern 으로 인해 개인적으로 interface에 대한 관심이 높아져서, 몇차례에 걸쳐서 정리해보려고 한다.


인터페이스 정의하기

인터페이스는 메서드 원형들의 집합에 이름을 붙인 것입니다.

공용 런타임과 이를 기반으로 하는 모든 관리 프로그래밍 언어들은 다중 상속을 지원하지 않습니다.
CLR은 인터페이스를 이용해서 축소된 형태의 다중상속을 지원합니다.

일반적으로 interface라는 용어는 "상이한 시스템간의 계약 정보를 표현하는 것" 이라고 정의할 수 있습니다.

C#의 예약어이면서, OOP의 기본개념으로 자리잡고 있는 Interface는 형태상으로 몇가지 특징이 있습니다.

 

 

 

1. 선언(Declaration)은 있고, 정의(Definition)은 없다.

2. 다중 상속이 가능하다.

3. C#의 Property는 내부적으로 메소드로 구현되기 때문에 포함할 수 있다.

4. C# 컴파일러는 인터페이스 메서드를 구현할때, public 으로 선언하도록 요구한다.

CLR은 인터페이스 메서드가 virtual 로 정의 할 것을 요구한다.
소스코드에서 메서드 구현시 명시적으로 virtual 키워드를 사용하지 않으면,
컴파일러가 해당 메서드에 virtual 과 seald 키워드를 포함시키며,
이 경우 이 클래스를 상속한 다른 클래스에서 인터페이스 메서드를 재정의 할 수 없다.
만약 명시적으로 메서드에 virtual 키워드를 지정하면, 상속한 다른 클래스에서 재정의 할 수 있다.

인터페이스의 제약

1. 인터페이스는 생성자 메서드를 정의 할 수 없다. 

2. 인터페이스는 정적 맴버도 정의 할 수 없다. 

3. 인터페이스 내에서는 형식들을 중첩 사용할 수 없다. (나열형, 구조체, 클래스, 인터페이스)

4. 인터페이스는 다른 인터페이스를 상속 받을 수 있지만, 구조체 또는 클래스로부터 상속받을 수 없다.

 

 


 

인터페이스? 추상클래스?

인터페이스는 간단하게 계약(contract)라고 정의 되며, 구현 없이 메서드 선언만 포함되어 있다.
인터페이스를 추상메서드만 담고 있는 추상 클래스라고 생각해도 될것같다.

abstract class Drawing 
{     
    public abstract void Draw();
    public abstract void Move(); 
} 
interface IDraw 
{     
    void Draw();
    void Move(); 
} 


그럼 추상 클래스를 사용하지 인터페이스를 왜 사용할까?
추상 클래스는 단일 상속이지만, 인터페이스는 다중상속이 가능하다.
추상클래스는 클래스로 정의된 타입이여서 다중 상속을 할 수 없지만, 인터페이스는 클래스가 아니기 때문에 다중상속이 허용된다.
인터페이스의 메서드를 자식 클래스에서 구현할 때는 반드시 public 접근 제한자를 명시해야 한다.
C#의 프로퍼티는 내부적으로 메소드로 구현되기 때문에 인터페이스에는 프로퍼티 역시 포함 할 수 있다.

 


 

인터페이스를 사용해야 하는 이유

모든 클래스에 대해 상위 인터페이스를 만들 필요는 없으나, 객체 간 호출이 많다면 인터페이스 분리가 좋다.

 

1. 외부 시스템에 제공할 서비스 또는 객체 정보를 직접적인 class가 아닌 "선언" 만을 제공한다.
2. 다중 상속에 따른 class의 표현을 여러가지로 가능하게 한다.
3. 의도하지 않은 속성/메소드 공개를 막기 위해서도 사용한다.
4. 실제 object 의 class 정보를 제공하고 싶지 않을 때 혹은 명확히 하고 싶을 때 사용한다. 

 

 


 

명시적 인터페이스

C#에서 메서드의 이름 앞에 해당 메서드를 정의한 인터페이스 이름을 접두사로 붙여서 메서드를 정의 하면, 
명시적 인터페이스 구현 메서드 (Explicit Interface Method Implementation, EIMI) 를 만들게 된다. 
또한 명시적 인터페이스 구현 메서드에는 virtual 키워드도 지정할 수 없으며, 재정의도 불가능 하다.
명시적 인터페이스 구현 메서드는 실제로는 타입 객체모델의 일부가 아니기 때문이다.

 

728x90

'Programming' 카테고리의 다른 글

[DI] 의존성 관리하기 (1)  (0) 2019.12.17
[DI] 의존성과 계층화  (0) 2019.12.16
[C#] interface 와 abstract class 의 차이  (0) 2019.12.12
MOCK을 활용한 .NET 단위 테스트  (0) 2019.12.05
BDD 중심의 시나리오 테스트  (0) 2019.12.02

+ Recent posts