왜 인터페이스가 유용한가요?


158

나는 한동안 C #에서 공부하고 코딩 해왔습니다. 그러나 여전히 인터페이스의 유용성을 알 수는 없습니다. 그들은 테이블에 너무 적은 것을 가져옵니다. 기능의 서명을 제공하는 것 외에는 아무것도하지 않습니다. 구현해야 할 기능의 이름과 서명을 기억할 수 있으면 필요하지 않습니다. 그들은 (인터페이스에서) 상기 함수가 상속 클래스에서 구현되도록하기 위해 있습니다.

C #은 훌륭한 언어이지만 때로는 Microsoft가 처음으로 여러 상속을 허용하지 않는 문제를 만든 다음 솔루션을 제공한다는 느낌을 주기도합니다.

그것은 제한된 코딩 경험에 기초한 나의 이해입니다. 인터페이스는 무엇입니까? 얼마나 자주 사용하며 어떻게 사용합니까?


55
"구현 될 필요가있는 기능의 이름과 서명을 기억할 필요가 없습니다." 이 문장은 정적 타입 언어장점을 조금 더 살펴 봐야 할 것 같다 .
Steven Jeuris

37
C #을 잊고 Java를 잊어 버리고 언어를 잊어 버리십시오. 단순히 OO의 관점에서 생각하고 있습니다. Robert C. Martin, Martin Fowler, Michael Feathers, Gang of Four 등과 같은 사람들로부터 당신의 생각을 넓히는 데 도움이 될만한 독서 자료를 선택하도록 권합니다.
Anthony Pegram

27
어떤 인터페이스가 유용한 지 실제로 이해하려면 2 년 이상이 걸렸습니다. 내 제안 : 디자인 패턴 연구. 대부분 인터페이스에 의존하기 때문에 왜 유용한 지 빠르게 이해할 수 있습니다.
Oliver Weiler

37
친구를 많이 배울 수 있습니다.
ChaosPandion

60
@ChaosPandion 우리 모두 배울 것이 많았습니다
kenwarner

답변:


151

그들은 (인터페이스에서) 상기 함수가 상속 클래스에서 구현되도록하기 위해 있습니다.

옳은. 이는 기능을 정당화 할 수있는 충분한 이점입니다. 다른 사람들이 말했듯이 인터페이스는 특정 방법, 속성 및 이벤트를 구현 해야하는 계약상의 의무 입니다. 정적으로 유형이 지정된 언어의 강력한 이점은 컴파일러가 코드가 의존하는 계약이 실제로 충족되는지 확인할 수 있다는 것입니다.

즉, 인터페이스는 계약 의무를 나타내는 상당히 약한 방법입니다. 계약 의무를보다 강력하고 융통성있게 표현하려면 최신 버전의 Visual Studio와 함께 제공되는 코드 계약 기능을 살펴보십시오.

C #은 훌륭한 언어이지만 언젠가는 Microsoft가 처음으로 여러 상속을 허용하지 않는 문제를 만든 다음 솔루션을 제공한다는 느낌을줍니다.

네가 좋아서 기뻐

모든 복잡한 소프트웨어 설계는 서로 충돌하는 기능의 무게를 측정하고 적은 비용으로 큰 이점을 제공하는 "스위트 스팟"을 찾으려고 노력한 결과입니다. 우리는 고통스러운 경험을 통해 구현 공유의 목적으로 다중 상속 허용하는 언어 가 상대적으로 적은 이점과 상대적으로 큰 비용 이 있다는 것을 배웠습니다 . 구현 세부 사항을 공유하지 않는 인터페이스에서만 다중 상속을 허용하면 대부분의 비용없이 다중 상속의 많은 이점을 얻을 수 있습니다.


"Microsoft는 다중 상속을 허용하지 않음으로써 문제를 만듭니다"라는 내용을 읽었으며 Eric Lippert가 이에 대해 말할 것이 있다고 생각했습니다.
구성자

이 답변과 더 관련이 있습니다 : Eric, 당신은 코드 어커를 코드 컨트랙트로 언급하고 있지만 불완전하게 불완전합니다. 정적 검사기는 가장 기본적인 계약 이외의 것은 시행 할 수 없습니다. 작은 프로젝트에서 코드 계약을 사용해 보았습니다. 입력 및 출력에 대해 할 수있는 모든 것을 지정하는 각 방법마다 수백 줄을 추가했지만 Assume배열 또는 열거 형 멤버와 같은 경우에는 너무 많은 호출 을 추가해야했습니다 . 모든 것을 추가하고 내가 가지고있는 정적으로 검증 된 엉망을 본 후에 나는 프로젝트의 품질을 떨어 뜨 렸기 때문에 소스 제어로 되돌아갔습니다.
구성자

17
@configurator : 완료 될 수 없기 때문에 불완전합니다. 임의 계약을 통한 정적 프로그램 검증은 정지 문제를 해결하는 것과 같습니다. 예를 들어, 메소드에 대한 인수는 Fermat의 마지막 정리에 대한 반례가되어야한다고 말하는 코드 계약을 작성할 수 있지만 정적 검증기는 그러한 인수가 없는지 확인할 수 없습니다. 정적 검증자가 우주의 열사 전에이 작업을 완료 할 것으로 예상한다면 신중하게 사용해야합니다. (BCL에 불충분하게 주석이 달렸다는 불만이있는 경우 : 동의합니다.)
Eric Lippert

2
하나의 메소드가 결과 배열이나 열거에 널이 포함되어 있지 않다고 약속하면 using 메소드가 널을 허용하지 않는 위치에서 값을 사용할 수 있음을 알 수 있습니다. 그것이 내가하지 않기를 기대 한 한 가지 일이며, 그것 없이는 사용하기에는 너무 중요했습니다. 다른 것은 단지 보너스입니다. 즉, 정적 검증을 완료 할 수 없다는 것을 알고 있으므로 계약에 의존하는 것이 좋은 대안이 아니라고 생각합니다.
구성자

9
"좋아서 기쁘다"+1 그리고 다른 모든 것들도.
Robert S.

235

여기에 이미지 설명을 입력하십시오

따라서이 예제에서 PowerSocket은 다른 객체에 대해 다른 것을 알지 못합니다. 개체는 모두 PowerSocket에서 제공하는 전원에 의존하므로 IPowerPlug를 구현하여 연결할 수 있습니다.

인터페이스는 서로에 대해 알 필요없이 개체가 함께 작업하는 데 사용할 수있는 계약을 제공하기 때문에 유용합니다.


4
이 IPowerPlug =) 구현과 같이 왼쪽 하단 객체는 보이지 않는다
스티븐 Striga

100
젠장, 그러나 다른 국가에서 IPowerPlug를 사용하려면 어댑터 패턴을 사용해야합니다!
Steven Jeuris

인터페이스를 해결하기 위해 장치를 제리로 리깅하는 것은 안전하지 않지만 (일부 사람들은 여전히 ​​테스트되지 않은 변명으로 성능을 인용하는 경우가 있습니다) 화재의 원인이 될 수 있습니다.
YoungJohn

4
이 답변은 놀랍습니다 ...
Mario Garcia

이 답변을 지적하는 것만으로는이 특정 예제에서 왜 인터페이스를 사용하는 것이 상속보다 선호되는지는 말하지 않습니다. 인터페이스를 처음 접하는 사람은 왜 모든 플러그 기능을 제공하는 MainsPoweredDevice와 MainsPoweredDevice에서 파생 된 소켓을 수용하는 소켓을 상속하지 않는지 묻습니다.
성분

145

기능의 서명을 제공하는 것 외에는 아무것도하지 않습니다. 구현해야 할 기능의 이름과 서명을 기억할 수 있으면 필요하지 않습니다.

인터페이스의 요점은 구현할 메소드를 기억하도록 돕기위한 것이 아니라 계약정의하는 것 입니다. 에서 foreach는 P.Brian.Mackey 예 (이 잘못된 것으로 판명 ,하지만 우리는 상관하지 않습니다)는 IEnumerable 사이의 계약 정의 의 foreach어떤 열거 일을. "당신이 누구든지, 당신이 계약 (구현 가능한 IEnumerable)을 고수하는 한, 나는 당신의 모든 요소를 ​​반복 할 것이라고 약속합니다." 그리고 그것은 훌륭합니다 (비 동적 언어의 경우).

인터페이스 덕분에 두 클래스간에 매우 낮은 결합을 달성 할 수 있습니다.



나는 "낙서 입력"이라는 용어를 사용하는 것을 싫어합니다. 왜냐하면 사람들마다 다른 것을 의미하기 때문입니다. "foreach"루프에 대해 패턴 일치를 사용합니다. 설계시 IEnumerable <T>를 사용할 수 없기 때문입니다. C # 형식 시스템이 너무 약해서 필요한 "모나드 패턴"을 캡처 할 수 없기 때문에 LINQ에 패턴 일치를 사용합니다. 하스켈 타입 시스템과 같은 것이 필요합니다.
Eric Lippert

@ 에릭 : "패턴 일치"도 같은 문제가 없습니까? 들었을 때 F # / Scala / Haskell이라고 생각합니다. 그러나 오리 타이핑보다 더 넓은 아이디어라고 생각합니다.
Daniel

@Daniel : 네, 그런 것 같습니다. 그것의 다른 것의 하나의 6 개와 6 개의 다른 것 같아요!
Eric Lippert

36

인터페이스는 분리 된 구조를 유지하는 가장 좋은 방법입니다.

테스트를 작성할 때 테스트 환경에서 구체적인 클래스가 작동하지 않음을 알게됩니다.

예 : 데이터 액세스 서비스 클래스 에 의존하는 클래스를 테스트하려고합니다 . 해당 클래스가 웹 서비스 또는 데이터베이스와 통신하는 경우 단위 테스트는 테스트 환경에서 실행되지 않으며 통합 테스트로 바뀝니다.

해결책? 사용하여 인터페이스를 사용자에 대한 데이터 액세스 서비스모의 당신이 하나의 단위로 클래스를 테스트 할 수 있도록 해당 인터페이스를.

반면, WPF 및 Silverlight는 바인딩과 관련하여 인터페이스와 전혀 호환되지 않습니다. 이것은 꽤 불쾌한 주름입니다.


2
들으세요! 다형성과 같은 다른 문제를 해결하기 위해 인터페이스가 개발되었습니다. 그러나 나를 위해 의존성 주입 패턴을 구현할 때 자체적으로 나옵니다.
andy

29

인터페이스는 (정적) 다형성의 중추입니다! 인터페이스가 중요합니다. 서브 클래스는 기본적으로 이미 구현 된 부모 인터페이스를 상속하므로 인터페이스 없이는 상속이 작동하지 않습니다.

얼마나 자주 당신이 그들을 사용하고 어떻게 그렇게합니까 ??

꽤 자주. 플러그 가능해야 할 모든 것은 내 응용 프로그램의 인터페이스입니다. 종종 같은 행동을 제공 해야하는 관련없는 수업이 있습니다. 상속과 같은 문제를 해결할 수 없습니다.

동일한 데이터에서 작업을 수행하기 위해 다른 알고리즘이 필요하십니까? 인터페이스를 사용 하십시오 (전략 패턴 참조 )!

다른 목록 구현을 사용 하시겠습니까? 인터페이스와 호출자에 대한 코드는 구현에 대해 걱정할 필요가 없습니다!

한 가지 이유로, 오랫동안 인터페이스에 대해 코딩하는 것이 OOP뿐만 아니라 모범 사례로 간주됩니다. 요구 사항에 맞지 않으면 구현을 쉽게 변경할 수 있습니다. 다중 상속으로 만 달성하려고 시도하거나 필요한 인터페이스를 제공하기 위해 빈 클래스를 작성하는 것으로 귀찮은 경우 꽤 번거 롭습니다.


1
다형성에 대해 들어 본 적이 없다면 다형성을 의미합니까?
Steven Jeuris

1
마이크로 소프트가 처음에 다중 상속을 허용했다면 인터페이스가 존재하는 이유는 없었을 것이다.
Pankaj Upadhyay

10
@Pankaj Upadhyay : 다중 상속과 인터페이스는 서로 다른 두 쌍의 신발입니다. 행동이 다른 두 개의 관련없는 클래스의 인터페이스가 필요한 경우 어떻게해야합니까? 다중 상속으로 해결할 수 없습니다. 어쨌든 별도로 구현해야합니다. 그런 다음 다형성 동작을 제공하려면 인터페이스를 설명 할 무언가가 필요합니다. 다중 상속은 많은 경우에 걸을 수있는 맹목적인 골목이며, 조만간 발로 자신을 쏘는 것은 너무 쉽습니다.
팔콘

1
단순화하자. 내 인터페이스가 Display 및 Comment라는 두 가지 기능을 구현하고 구현하는 클래스가 있습니다. 그렇다면 인터페이스를 제거하고 기능을 직접 사용하지 않는 이유는 무엇입니까? 내가 말하는 것은 단지 구현에 필요한 함수의 이름을 제공한다는 것입니다. 만약 그 함수들을 기억할 수 있다면 왜 인터페이스를 만드십시오
Pankaj Upadhyay

9
@Pankaj, 인터페이스가 필요한 모든 것이라면 사용하지 마십시오. 클래스의 모든 측면을 무시하고 인터페이스의 기본 유형 (예 : 인터페이스)으로 액세스하려는 프로그램이있을 때 인터페이스를 사용하십시오. 서브 클래스를 알 필요는 없으며 인터페이스의 유형에 불과합니다. 따라서 객체 인터페이스에 대한 참조를 통해 서브 클래스의 구현 된 메소드를 호출 할 수 있습니다. 이것은 기본 상속 및 디자인 요소입니다. 그렇지 않으면 C를 사용할 수도 있습니다. 명시 적으로 사용하지 않더라도 프레임 워크가 없으면 프레임 워크가 작동하지 않습니다.
Jonathan Henson

12

아마도 foreach이것을 사용 하고 꽤 유용한 반복 도구라는 것을 알았습니다. 작동하려면 인터페이스가 필요하다는 것을 알고 있습니까? IEnumerable ?

인터페이스의 유용성에 대한 확실한 사례입니다.


5
실제로 foreach에는 IEnumerable이 필요하지 않습니다. msdn.microsoft.com/en-us/library/9yb8xew9%28VS.80%29.aspx
Matt H

1
나는 모든 것을 연구했지만 다른 손으로 귀를 잡고있는 것과 같습니다. 상속이 여러 번 허용되면 인터페이스가 크게 선택되었을 것입니다.
Pankaj Upadhyay

2
인터페이스는 종종 상속되는 여러 상속입니다. 그러나 동작 및 상태의 다중 상속을 허용하지 않습니다. 믹스 인 또는 특성은 행동의 다중 상속을 허용하지만 공유 상태는 문제를 야기하지
Matt H

@Pankaj, 주 제외이지만 모국어가 무엇인지 물어봐도 될까요? "다른 손으로 귀를 잡는 것"은 훌륭한 관용구이며 그것이 어디서 나오는지 궁금했습니다.
케빈

3
@ 아이스 맨. LOL .... 나는 인도 출신입니다. 그리고 여기에는 쉬운 일을 어려운 방식으로하는 것을 반영하는 일반적인 관용구가 있습니다.
Pankaj Upadhyay

11

인터페이스는 플러그가 가정용 배선과 같은 객체를 코딩하는 것입니다. 라디오를 집 배선에 직접 납땜 하시겠습니까? 청소기는 어때요? 당연히 아니지. 플러그와 콘센트가 집 배선과 전원이 필요한 장치 사이의 "인터페이스"를 형성합니다. 집 배선은 3 구 접지 플러그를 사용하고 120VAC <= 15A에서 전력을 필요로하는 것 외에는 장치에 대해 아무것도 알 필요가 없습니다. 반대로, 장치는 120VAC <= 15A를 제공하는 하나 이상의 3 구 콘센트가 편리하게 위치한 것 외에는 집이 어떻게 배선되어 있는지에 대한 확실한 지식이 필요하지 않습니다.

인터페이스는 코드에서 매우 유사한 기능을 수행합니다. 객체는 특정 변수, 매개 변수 또는 반환 유형이 인터페이스 유형임을 선언 할 수 있습니다. 인터페이스는 new키워드로 직접 인스턴스화 할 수 없지만 내 객체는 해당 인터페이스의 구현을 제공하거나 찾을 수 있습니다. 일단 객체가 의존성을 가지면, 그 의존성이 무엇인지 정확히 알 필요가 없으며, 의존성에 대해 메소드 X, Y 및 Z를 호출 할 수 있다는 것을 알아야합니다. 인터페이스의 구현은 사용 방법을 알 필요가 없으며 메소드 X, Y 및 Z에 특정 서명을 제공해야한다는 것을 알아야합니다.

따라서 동일한 인터페이스 뒤에있는 여러 객체를 추상화하여 해당 인터페이스의 모든 객체 소비자에게 공통된 기능 세트를 제공합니다. 예를 들어 List, Dictionary, LinkedList, OrderedList 등의 개체를 알 필요는 없습니다. 이들 모두가 IEnumerable이라는 것을 알고 있으므로 IEnumerable의 메소드를 사용하여 한 번에 하나씩 이러한 콜렉션의 각 요소를 살펴볼 수 있습니다. 출력 클래스가 ConsoleWriter, FileWriter, NetworkStreamWriter 또는 다른 유형의 작성자를 사용하는 MulticastWriter인지 알 필요는 없습니다. 여러분이 알아야 할 것은 모두 IWriter (또는 무엇이든)이므로 문자열을 전달할 수있는 "쓰기"메서드가 있으며 해당 문자열이 출력됩니다.


7

프로그래머가 (처음에는 최소한) 다중 상속을받는 것은 분명한 치료법이지만, 이것은 거의 사소한 생략이므로 다중 상속에 의존해서는 안됩니다 (대부분의 경우). 그 이유는 복잡하지만 실제로 배우고 싶다면 C ++ 및 Python (3 및 8 번째)을 지원하는 가장 유명한 두 가지 ( TIOBE 색인 기준 ) 프로그래밍 언어 의 경험을 고려하십시오 .

파이썬에서는 다중 상속이 지원되지만 프로그래머가 거의 보편적으로 오해하고 있으며 그것이 작동하는 방식을 알고 있다고 말하는 것은 메소드 해결 순서 주제 에서이 백서를 읽고 이해하는 것을 의미합니다 . 파이썬에서 일어난 또 다른 것은 Zope.Interfaces라는 언어에 대한 인터페이스입니다.

C ++의 경우, 구글 "다이아몬드 계층 구조 C ++"를보고 당신을 덮고 자하는 추악함을 보라. C ++ 전문가는 다중 상속을 사용하는 방법을 알고 있습니다. 다른 사람들은 대개 결과가 무엇인지 모른 채 놀고 있습니다. 인터페이스가 얼마나 유용한 지 보여주는 또 다른 것은 많은 경우 클래스가 부모의 동작을 완전히 재정의해야 할 수도 있다는 것입니다. 이러한 경우 부모 구현은 불필요하며 C # 시대에는 중요하지 않지만 임베디드 프로그래밍을 수행 할 때 중요한 부모의 개인 변수에 대한 메모리만으로 자식 클래스에 부담을줍니다. 인터페이스를 사용하면 해당 문제가 존재하지 않습니다.

결론적으로 인터페이스는 계약을 시행하기 때문에 OOP의 필수 부분입니다. 다중 상속은 제한된 경우에 유용하며 일반적으로 사용 방법을 알고있는 사람에게만 유용합니다. 따라서 초보자 인 경우 다중 상속이 부족하여 치료를받는 사람입니다. 이렇게하면 실수하지 않을 수있는 더 좋은 기회가됩니다 .

또한 역사적으로 인터페이스에 대한 아이디어는 Microsoft의 C # 디자인 사양보다 훨씬 빠릅니다. 대부분의 사람들은 C #을 Java에 대한 업그레이드 (대부분의 의미에서)로 간주하고 C #이 Java에서 인터페이스를 가져온 위치를 추측합니다. 프로토콜은 같은 개념의 오래된 단어이며 .NET보다 오래된 것입니다.

업데이트 : 이제 인터페이스가 다중 상속 대신 왜 다른 질문에 대답했을 수도 있지만 이것이 당신이 찾고있는 대답처럼 보였습니다. OO 언어 외에 두 언어 중 하나 이상이 있어야하며 다른 답변은 원래 질문을 다룹니다.


6

인터페이스를 사용하지 않고 깨끗하고 객체 지향적 인 C # 코드를 상상하기는 어렵습니다. 클래스가 특정 기본 클래스에서 상속받지 않고 특정 기능의 가용성을 강화하려고 할 때마다이를 사용하면 코드에서 관련 수준의 (낮은) 커플 링을 가질 수 있습니다.

다중 상속이 자체 통증 세트와 함께 제공된다고 주장하기 전에도 다중 상속이 인터페이스를 갖는 것보다 낫다는 데 동의하지 않습니다. 인터페이스는 다형성 및 코드 재사용을 가능하게하는 기본 도구입니다. 더 필요한 것은 무엇입니까?


5

나는 개인적으로 추상 클래스를 좋아하고 인터페이스보다 더 많이 사용합니다. 주요 차이점은 IDisposable, IEnumerable 등과 같은 .NET 인터페이스와 COM interop과의 통합에 있습니다. 또한 인터페이스는 추상 클래스보다 작성하는 노력이 적으며 클래스는 하나의 클래스에서만 상속 할 수있는 동안 하나 이상의 인터페이스를 구현할 수 있습니다.

즉, 인터페이스를 사용하는 대부분의 항목이 추상 클래스에서 더 잘 제공 된다는 것을 알았습니다. 순수 가상 함수 (추상 함수)를 사용하면 인터페이스에서 구현자가 모든 멤버를 정의하도록 강제하는 방식과 유사한 기능을 구현자가 강제로 정의 할 수 있습니다.

그러나 일반적으로 수퍼 클래스에 특정 디자인을 적용하지 않으려는 경우 인터페이스를 사용하는 반면 추상 클래스를 사용하여 이미 구현 된 재사용 가능한 디자인을 갖습니다.

System.ComponentModel 네임 스페이스를 사용하여 플러그인 환경을 작성하는 데 인터페이스를 광범위하게 사용했습니다. 그들은 매우 편리합니다.


1
잘 넣어! 추상적 클래스에 대한 기사를 좋아할 것 같습니다. 추상화는 모든 것 입니다.
Steven Jeuris

5

나는 그것에 관련이 있다고 말할 수 있습니다. OO와 C #에 대해 처음 배우기 시작했을 때 인터페이스도 얻지 못했습니다. 괜찮아. 우리는 인터페이스의 편의성을 높이기 위해 무언가를 가져와야합니다.

두 가지 접근 방식을 시도하겠습니다. 그리고 일반화를 위해 나를 용서하십시오.

시도 1

영어를 모국어로 사용한다고 가정 해 보겠습니다. 영어가 모국어가 아닌 다른 국가로갑니다. 도움이 필요합니다. 당신을 도울 수있는 사람이 필요합니다.

"이봐 요, 미국에서 태어 났나요?" 이것이 상속입니다.

아니면 "이봐, 영어 할 줄 알아?" 인터페이스입니다.

그것이하는 일에 관심이 있다면, 인터페이스에 의존 할 수 있습니다. 당신이 무엇인지에 관심이 있다면, 당신은 상속에 의존합니다.

상속에 의존해도 괜찮습니다. 영어를하고, 차를 좋아하고, 축구를 좋아하는 사람이 필요하다면 영국인을 요구하는 것이 좋습니다. :)

시도 2

좋아, 다른 예를 들어 보자.

다른 데이터베이스를 사용하고 작업하려면 추상 클래스를 구현해야합니다. DB 공급 업체에서 클래스를 일부 클래스로 전달합니다.

public abstract class SuperDatabaseHelper
{
   void Connect (string User, string Password)
}

public abstract class HiperDatabaseHelper
{
   void Connect (string Password, string User)
}

다중 상속이라고합니까? 위의 경우로 시도하십시오. 당신은 할 수 없습니다. 컴파일러는 어떤 Connect 메서드를 호출하려고하는지 알 수 없습니다.

interface ISuperDatabaseHelper
{
  void Connect (string User, string Password)
}

interface IHiperDatabaseHelper
{
   void Connect (string Password, string User)
}

이제 C #에서는 인터페이스를 명시 적으로 구현할 수있는 작업이 있습니다.

public class MyDatabaseHelper : ISuperDatabaseHelper, IHiperDatabaseHelper
{
   IHiperDataBaseHelper.Connect(string Password, string User)
   {
      //
   }

   ISuperDataBaseHelper.Connect(string User, string Password)
   {
      //
   }

}

결론

예제는 최고는 아니지만 포인트가 맞다고 생각합니다.

인터페이스가 필요할 때만 "얻을"수 있습니다. 그들까지 당신은 그들이 당신을위한 것이 아니라고 생각할 것입니다.


첫 번째 시도는 내 투표를 한 것입니다.
osundblad

1
나는 지금부터 미국 대 영어 스피커 유추를 완전히 사용하고 있습니다. 환상적입니다.
Bryan Boettcher

더 간단한 방법으로 설명했다! 환상적인.
Aimal Khan

4

두 가지 주요 이유가 있습니다.

  1. 다중 상속 부족 하나의 기본 클래스에서 상속하고 여러 인터페이스를 구현할 수 있습니다. 이것이 .NET에서 다중 상속을 "할"유일한 방법입니다.
  2. COM 상호 운용성 "이전"기술에서 사용해야하는 것은 인터페이스를 정의해야합니다.

포인트 1은 Microsoft 개발자가 직접 개발 한 이유와 이유입니다.
Pankaj Upadhyay

1
@Pankja 실제로, 그들은 C #의 기능 중 좋은 부분과 같은 Java의 인터페이스 아이디어를 취했습니다.
Oliver Weiler

3

인터페이스를 사용하면 시스템이 분리되어 리팩토링, 변경 및 재배치가 쉬워집니다. 그것은 객체 지향적 정설에 대한 핵심 개념이며, C ++ 전문가들이 "순수한 추상 클래스"를 만들었을 때 처음으로 그것에 대해 배웠습니다.


디커플링은 시스템의 서로 다른 구성 요소를 서로 독립적으로 유지하기 때문에 중요합니다. 한 구성 요소의 큰 변경 사항이 다른 구성 요소에도 영향을 미치지 않습니다. 전원 플러그를 유틸리티 회사의 인터페이스 (전압 및 물리적 핀 및 플러그 형식 지정)로 생각하십시오. 이 인터페이스 덕분에이 유틸리티는 전력 생산 방식 (예 : 태양 광 기술 사용)을 완전히 변경할 수 있지만, 어떤 장치도 변화를 눈치 채지 못할 것입니다.
miraculixx

3

인터페이스 자체는 그다지 유용하지 않습니다. 그러나 구체적인 클래스로 구현하면 하나 이상의 구현을 할 수있는 유연성이 제공됩니다. 보너스는 인터페이스를 사용하는 객체가 실제 구현의 세부 사항이 어떻게 진행되는지 알 필요가 없다는 것입니다. 즉, 캡슐화라고합니다.


2

주로 코드 재사용에 사용됩니다. 인터페이스에 코드를 작성하면 해당 인터페이스에서 상속되고 모든 것을 중단하지 않는 다른 클래스를 사용할 수 있습니다.

또한 웹 서비스에서 매우 유용하여 클라이언트에게 클래스의 기능을 알려주고 (소비 가능) 실제 코드를 제공하고 싶지 않습니다.


2

젊은 프로그래머 / 개발자로서 C #을 배우기 만하면 클래스를 사용하여 코드를 작성할 수 있고 코드가 제대로 작동하기 때문에 인터페이스의 유용성이 보이지 않을 수 있지만 실제 시나리오에서는 확장 가능하고 강력하며 유지 관리 가능한 응용 프로그램을 작성해야합니다. 인터페이스를 사용해서 만 가능할 수있는 일부 아키텍처와 패턴은 의존성 주입에 있습니다.


1

실제 구현 :

인터페이스 유형으로 객체를 캐스트 할 수 있습니다.

IHelper h = (IHelper)o;
h.HelperMethod();

인터페이스 목록을 만들 수 있습니다

List<IHelper> HelperList = new List<IHelper>();

이러한 객체를 사용하면 인터페이스 방법 또는 속성에 액세스 할 수 있습니다. 이러한 방식으로 프로그램의 일부에 대한 인터페이스를 정의 할 수 있습니다. 그리고 그 주위에 논리를 구축하십시오. 그런 다음 다른 사람이 자신의 비즈니스 객체에서 인터페이스를 구현할 수 있습니다. BO가 변경되면 인터페이스 구성 요소의 로직을 변경할 수 있으며 사용자의 로직을 변경할 필요가 없습니다.


0

인터페이스는 클래스가 시스템이 전달하는 특정 종류의 메시지를 이해하고 구독 할 수있는 메커니즘을 제공함으로써 플러그인 스타일의 모듈성을 제공합니다. 자세히 설명하겠습니다.

응용 프로그램에서 양식을로드하거나 다시로드 할 때마다 호스팅하는 모든 항목을 지우고 자 결정합니다. IClear구현 하는 인터페이스를 정의합니다 Clear. 또한 사용자가 저장 버튼을 눌렀을 때마다 양식의 상태를 유지해야한다고 결정합니다. 따라서 준수하는 모든 ISave메시지는 상태를 유지하라는 메시지를받습니다. 물론 실제로 대부분의 인터페이스는 여러 메시지를 처리합니다.

인터페이스를 차별화하는 것은 상속없이 일반적인 동작을 수행 할 수 있다는 것입니다. 지정된 인터페이스를 구현하는 클래스는 단순히 명령을 실행할 때 동작하는 방법 (명령 메시지) 또는 쿼리 할 때 응답하는 방법 (쿼리 메시지)을 이해합니다. 기본적으로 응용 프로그램의 클래스는 응용 프로그램이 제공하는 메시지를 이해합니다. 따라서 플러그를 꽂을 수있는 모듈 식 시스템을보다 쉽게 ​​구성 할 수 있습니다.

대부분의 언어에는 인터페이스를 따르는 것들을 쿼리 하는 메커니즘 ( LINQ 등 )이 있습니다. 이것은 (특정 메시지에 따라) 유사하게 동작하는 방법을 (동일한 상속 체인에서 파생되지 않은) 유사하게 말할 필요가 없기 때문에 일반적으로 조건부 논리를 제거하는 데 도움이됩니다. 대신, 특정 메시지를 이해하는 모든 것을 수집하고 (인터페이스를 통해) 메시지를 게시합니다.

예를 들어 다음을 대체 할 수 있습니다.

Me.PublishDate.Clear()
Me.Subject.Clear()
Me.Body.Clear()

...와:

For Each ctl As IClear In Me.Controls.OfType(Of IClear)()
    ctl.Clear()
Next

효과적으로 다음과 같이 들립니다.

들어 봐, 들어 봐! 삭제를 이해하는 모든 사람이 Clear지금 부탁합니다 !

이런 식으로, 우리는 프로그램 적으로 모든 것을 스스로 지우라고 말하는 것을 피할 수 있습니다. 또한 미래에 삭제 가능한 항목이 추가되면 추가 코드없이 간단히 응답합니다.


0

다음은 의사 코드입니다.

class MyClass{

    private MyInterface = new MyInterfaceImplementationB();

    // Code using Thingy 

}

interface MyInterface{

    myMethod();

}

class MyInterfaceImplementationA{ myMethod(){ // method implementation A } }

class MyInterfaceImplementationB{ myMethod(){ // method implementation B } }

class MyInterfaceImplementationC{ myMethod(){ // method implementation C } }

마지막 클래스는 완전히 다른 구현 일 수 있습니다.

다중 상속이 가능하지 않으면 상속은 부모 클래스를 구현하여 일을보다 엄격하게 만듭니다. 반면에 인터페이스에 대한 프로그래밍은 코드 또는 프레임 워크를 매우 유연하게 만들 수 있습니다. 상속 체인에서 클래스를 바꿀 수 있기를 원했던 경우가 발생하면 그 이유를 이해할 수 있습니다.

예를 들어, 원래 디스크에서 데이터를 읽도록 의도 된 Reader를 제공하는 프레임 워크는 완전히 다른 방식으로 동일한 성질을 가진 무언가를 수행하도록 다시 구현 될 수 있습니다. 예를 들어 모스 코드를 해석하는 것과 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.