White Whale Studio

Interface에 대한 탐구 본문

IT Engineering/C#.net

Interface에 대한 탐구

glorymind 2016. 6. 7. 15:13
반응형

인터페이스(Interface)에 대한 탐구를 진행합니다.


인터페이스는 많이 들어보기는 했습니다만, 실제적으로 사용하기에는 개념자체가 접근하기가 어렵고 

작은 프로젝트로 구현되는 프로그램에서 굳이 사용하지 않아도 되었기에 주먹구구식으로 진행되는 

개발시에는 굳이 사용하지 않았습니다.


그러나 객체지향프로그래밍(OOP)을 위해서 이것저것 학습을 하던 차에 인터페이스에 대한

내용을 재확인하고 그 유용성에 대해 깨닫게 되었습니다.

우선 인터페이스의 장점은 여러가지가 있다고 하는데

부끄럽게도 제가 알고 있는 장점은 겨우 2가지 정도입니다.

1. 개발자들간의 개발 규약

2. 인터페이스를 상속받는 클래스는 형식이 무엇이 되든간에 인터페이스 형식으로 타입 캐스팅이 되어서 클래스 사용하기가 엄청 쉽다.


우선 인터페이스의 특징을 살펴보면

1. 자신에게서 상속받을 클래스가 구현해야할 기능을 나열(실제 구현은 하지 않는 추상 메소드)

2. 인터페이스 상속은 클래스의 상속과 동일하다.

3. 오버라이드할때 new 혹은 override 키워드를 사용하지 않고 클래스 내에서 구현합니다.

(VS에서 빌드했을 시 구현이 되어있지 않으면 에러가 발생하므로 구현을 쉽게하려면 명시적 구현을 이용하셔도 편리합니다.)

4. 다중상속 가능(일반 클래스는 다른 클래스를 오직 하나만 부모 클래스로 선택하여 상속가능하나 인터페이스는 다중으로 가능)

5. 메소드, 이벤트, 인덱서, 속성, 프로퍼티 선언 가능(프로퍼티 내 구현은 불가), 필드는 선언 불가


위와 같습니다. 다른 특징들도 있지만 일단은 위의 정도로 나열할 수 있습니다.


인터페이스의 장점 중 

1번에 대해서 간단하게 예시를 들자면

USB를 예로 들면 쉬울 것같습니다. USB는 디바이스와 컴퓨터를 연결하는 특정한 약속이며

USB 포트에 연결할 수 있다면 USB 선풍기, 확장 케이블, USB메모리, USB 외장하드, USB LED 등등의 다양한 기능을 수행할 수 있습니다.

여기서 인터페이스를 표현한다면 USB 포트라고 볼수 있겠습니다.

USB를 통한 전류 공급, 데이터 송수신 등이 메소드로 구현될수 있겠지요.

즉, 특정한 행위 혹은 형태만 만족한다면(특징 중 5번 항목) 어떠한 객체든지 받아들이겠다는 것입니다.


2번에 대해서 실제적으로 한번 살펴보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface IService
    {
        string SetService(string order);
    }
 
public interface IDiscount
    {
        double Get3p1Discount(double totalSales);
        double Get2p1Discount(double totalSales);
 
        decimal discountPrice
        {
            get; set;
        }
    }
cs

위와 같이 Discount 인터페이스를 선언하고 3+1 할인 함수와 2+1 할인 메소드를 선언하고 할인가격 프로퍼티를 선언했습니다.

또한 Service 인터페이스를 선언하고 여기는 메소드만 선언했습니다.


이 인터페이스들을 상속받는 클래스는 SilverCustomer 와 GoldCustomer 이며

인터페이스를 상속받았으므로 구현을 해야만합니다.

각각 동일한 함수와 프로퍼티를 구현하는데 하나만 써보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class GoldCustomer : OC_Customer, IService, IDiscount
    {
        public string SetService(string order)
        {
            return "Coupon 3A Served";
        }
 
        public double Get3p1Discount(double totalSales)
        {
            throw new NotImplementedException();
        }
 
        public double Get2p1Discount(double totalSales)
        {
            throw new NotImplementedException();
        }
 
 
        public decimal discountPrice
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }
cs


위에서 보는 바와 같이 IService에서는 SetService를 상속받아 오버라이드하고 IDiscount에서는 Get3p1Discount, Get2p1Discount, discountPrice를 

상속받아 오버라이드하였습니다. 실제적인 구현은 필요에 따라 구현합니다.


이와 같이 구현을 하고

실제적으로 GoldCustomer를 사용해보겠습니다.


IDiscount idis = new GoldCustomer();

IService iserve = new GoldCustomer();


위와 같이 해당 인터페이스를 상속받은 자식 객체의 경우 그 형식이 무엇이든간에 Interface로 타입캐스팅이 가능합니다.

따라서 함수나 프로퍼티에 접근하기가 용이해 지죠. 

이와 같이 Interface를 상속함으로써 GoldCustomer는 다형성을 가지게 됩니다.


편리한 예를 들자면 인터페이스를 상속받아 패널에 무작위의 컨트롤을 올려야만 할때 인터페이스를 상속받은 컨트롤들을 오버라이드하여 구현한 뒤

올려야 한다면 일반적으로는 엄청난 반복 작업을 해야만 하지만

인터페이스를 활용한다면

상속받은 메소드 혹은 프로퍼티는 인터페이스를 통해 접근 가능하므로 단 몇줄이면 처리가 가능합니다.

예를 들어 각 컨트롤 별로 고유 ID값을 부여한다고 했을 때 인터페이스에서는 

public interface Iidentification

    {

        public string idNo

        {

            get;

            set;

        }

    }

위와 같이 선언하고 

필요한 컨트롤들은 이 Iidentification 인터페이스를 상속받아 각각 idNo를 구현한다고 합시다.


그러면 단순무식한 방법으로는

Button btn = new Button();

btn.idNo = 1;

CheckButton chkbtn = new CheckButton();

chkbtn.idNo = 2;

RadioButton rdbtn = new RadioButton();

rdbtn.idNo = 3;


위와 같이 구현을 했다면


Iidentification _controlChild = _control[0] as Iidentification;

_controlChild.idNo = count++;



위와 같은 방식으로 단순화 될수 있습니다.

동일한 방식으로 C#에서 제공하는 각종의 컬렉션 클래스들 역시 인터페이스를 사용해서 컬렉션에 포함된 각 객체의 형식이 무엇이든

foreach, 문으로 접근 가능하다고 하네요.

반응형
Comments