Open-Closed Principle

[C#] 명시적 인터페이스(Interface) 구현 본문

Programming/C#

[C#] 명시적 인터페이스(Interface) 구현

대박플머 2014. 6. 17. 09:29

C++을 해본사람은 다중상속에 대해 알고 있을 것이다. 

그런데 다중상속은 많은 문제점을 갖고 있다. 

그래서 C#에서는 다중상속 자체를 문법적으로 제한하면서 Interface라는 높은 차원의 추상화 클래스를 만들었다. 

여기서 이야기 하고 싶은것은 Interface의 사용법이다.

예를 들어 이런 상황이 있다고 가정해보자. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
 
public class Program{
    public static void Main(){
        SampleClass sc = new SampleClass();
        sc.PrintMessagebox();
        sc.PrintForm();
    }
}
 
public class SampleClass{
    public void PrintMessagebox(){
        Console.WriteLine("Messagebox Print!");
    }
    public void PrintForm(){
        Console.WriteLine("Form Print!");
    }
}

이런 경우 interface의 필요성이 대두 된다. 사용자는 Form과 MessageBox가 출력이 되는 형태를 구현해야 한다. 여기까지는 다른 형태이기 때문에 어떤 상황이여도 구현은 불가피하다. 하지만 이름을 매번 정해줘야 한다. Print라는 이름 뒤에 어떤 Control의 Print인지 함수를 만들어야 하는 것이다. 

그런데 Interface를 사용하면 한가지 이름으로 통일 할 수 있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
 
public class Program{
    public static void Main(){
        SampleClass sc = new SampleClass();
        sc.Print(); // A
    }
}
 
public interface IMessageBox{
    void Print();
}
public interface IForm{
    void Print();
}
 
public class SampleClass : IMessageBox, IForm{
    public void Print(){
        Console.WriteLine("????????");
        // 이 녀석은 누구의 Print일까?
    }    
}

그런데 SmapleClass의 구현된 Print함수는 누구의 Interface일까?

// A 부분을 인터페이스 호출로 Print를 호출해보면 알수 있게 될 것이다. 

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
using System;
 
public class Program{
    public static void Main(){
        SampleClass sc = new SampleClass();
        IMessageBox messageBox = sc;
        messageBox.Print();
        IForm form = sc;
        form.Print();
    }
}
 
public interface IMessageBox{
    void Print();
}
public interface IForm{
    void Print();
}
 
public class SampleClass : IMessageBox, IForm{
    public void Print(){
        Console.WriteLine("Print");
    }    
}
 
/*output
Print
Print
*/
 

이렇게 인터페이스를 통해서 함수를 호출해보면 output과 같이 나온다. 

바로 이부분에서 명시적인 Interface를 사용할 필요가 있다. 

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
using System;
 
public class Program{
    public static void Main(){
        SampleClass sc = new SampleClass();
        IMessageBox messageBox = sc;
        messageBox.Print();
        IForm form = sc;
        form.Print();
    }
}
 
public interface IMessageBox{
    void Print();
}
public interface IForm{
    void Print();
}
 
public class SampleClass : IMessageBox, IForm{
    public void IMessageBox.Print(){
        Console.WriteLine("MessageBox Print");
    }    
    public void IForm.Print(){
        Console.WriteLine("Form Print");
    }
}

이렇게 하면 어떻게 될까??? 소스를 복사 붙여 넣기 해서 한번 돌려보길 바란다. 명시적으로 Interface의 이름을 적어주면 

이름을 확인하여 각자 자신의 Print를 찾아 간다는 것을 알게 될 것이다. 

인터페이스를 설계하다보면 이름을 명명할때 고민을 할 때가 많다. 그래서 같은 이름이 있을 경우 상위 인터페이스를 또 만들어 사용하기도 한다. 하지만 이렇게 명시적으로 Interface를 구현함으로써 부분적으로 일을 해결 할 수 있지 않을까 싶다. 


세상에서 함수, 클래스, 인터페이스, 변수 등을 Naming하는게 제일 어려운것 같다. 

이상 끝.......

'Programming > C#' 카테고리의 다른 글

[C#] Access 2003과 연동(1)  (0) 2014.06.24
[C#] Nullable 사용법  (0) 2014.06.19
[C#] Cross Thread로인한 InvalidOperationException해결법  (0) 2014.06.16
[C#] 람다 표현식  (0) 2014.06.16
[C#] 내부 클래스  (1) 2014.06.16