객체 지향 프로그래밍에서 "인터페이스"의 정의는 무엇입니까?


108

좋아, 내 친구가 프로그래밍에서 "인터페이스"가 의미하는 바를 앞뒤로 이동합니다.

"인터페이스"에 대한 가장 좋은 설명은 무엇입니까?

나에게 인터페이스는 클래스의 청사진입니다. 이것이 가장 좋은 정의입니까?


1
속임수는 아니지만이 질문에 많은 빛을 비
춥니 다

나는 그것이 일반적인 단어라고 말하고 싶지만 여전히 나에게는 같은 의미입니다. 그것은 외부에 일부 입력 지점을 제공하고 내부 작업에 대한 지식없이 출력을 제공하는 특정 또는 더 추상적 인 엔티티의 벽과 같습니다. OOP에서 더 낮은 수준에서 더 높은 수준의 클래스를 정의하는 추상화라고 할 수 있다고 생각합니다.
ikbal

답변:


179

인터페이스는 개발 과정에서 과부하되고 혼란스러운 용어 중 하나입니다.

실제로 추상화와 캡슐화의 개념입니다. 주어진 "상자"에 대해 해당 상자 의 "입력"및 "출력"을 선언 합니다. 소프트웨어 세계에서 이는 일반적으로 상자에서 (인수와 함께) 호출 할 수있는 작업과 경우에 따라 이러한 작업의 반환 유형을 의미합니다.

이것이하지 않는 것은 이러한 연산의 의미가 무엇인지 정의하는 것입니다. 그러나 선언에 근접하여 (예 : 주석을 통해) 문서화하거나 좋은 명명 규칙을 선택하는 것이 일반적이고 (매우 좋은 관행)이지만. 그럼에도 불구하고 이러한 의도를 따를 것이라는 보장은 없습니다.

비유는 다음과 같습니다. TV가 꺼져있을 때 TV를 살펴보십시오. 인터페이스는 버튼, 다양한 플러그 및 화면입니다. 의미와 동작은 입력 (예 : 케이블 프로그래밍)을 받고 출력 (화면 표시, 사운드 등)을 갖는다는 것입니다. 그러나 연결되지 않은 TV를 보면 예상되는 의미를 인터페이스에 투영하는 것입니다. 아시다시피 TV를 꽂으면 폭발 할 수 있습니다. 그러나 "인터페이스"를 기반으로하면 물을 마시지 않기 때문에 커피를 만들지 않을 것이라고 가정 할 수 있습니다.

객체 지향 프로그래밍에서 인터페이스는 일반적으로 해당 인터페이스가있는 클래스의 인스턴스가 응답 할 수있는 메서드 (또는 메시지) 집합을 정의합니다.

혼란을 더하는 것은 Java와 같은 일부 언어에는 언어 별 의미 체계를 가진 실제 인터페이스가 있다는 것입니다. 예를 들어 Java에서는 구현이없는 메서드 선언 집합이지만 인터페이스도 유형에 해당하고 다양한 입력 규칙을 따릅니다.

C ++와 같은 다른 언어에서는 인터페이스가 없습니다. 클래스 자체는 메서드를 정의하지만 클래스의 인터페이스를 비공개 메서드의 선언으로 생각할 수 있습니다. C ++ 컴파일 방식으로 인해 실제 구현없이 클래스의 "인터페이스"를 가질 수있는 헤더 파일을 얻을 수 있습니다. 순수 가상 함수 등을 사용하여 추상 클래스로 Java 인터페이스를 모방 할 수도 있습니다.

인터페이스는 확실히 클래스의 청사진이 아닙니다. 하나의 정의에 따르면 청사진은 "상세한 행동 계획"입니다. 인터페이스는 행동에 대해 아무것도 약속하지 않습니다! 혼란의 원인은 대부분의 언어에서 일련의 메소드를 정의하는 인터페이스 유형이있는 경우이를 구현하는 클래스가 동일한 메소드를 "반복"하므로 (정의를 제공함) 인터페이스가 골격 또는 수업 개요.


Objective-C에 관한 책을 읽고 있는데 저자들은 "프로토콜"과 "인터페이스"라는 용어를 같은 의미로 사용하는 것 같습니다. "프로토콜"과 "인터페이스"가 동일하다고 말하는 것이 맞습니까, 아니면 뭔가 빠졌습니까?
Fazzolini

1
나는 "인터페이스"에 "프로토콜"이라는 단어를 사용하지 않을 것입니다. "프로토콜"이라는 단어는 작업이 수행되는 방법에 대한 세부 수준을 의미합니다. "인터페이스"는 정말로 그것이 무엇인지 정확하게 설명하는 순수한 영어 정의를 가진 훌륭한 단어입니다.
OCDev

Windows 프로그래밍 인터페이스는 매우 광범위하게 사용되므로 C ++에서도 구현에서 분리 된 개체 방식으로 "인터페이스" 를 만날 수 있습니다 .
Victoria

166

다음 상황을 고려하십시오.

좀비가 갑자기 당신을 공격 할 때 당신은 크고 빈 방 한가운데에 있습니다.

무기가 없습니다.

운 좋게도, 살아있는 동료가 방의 출입구에 서 있습니다.

"빨리!" 당신은 그에게 소리 친다. "좀비를 때릴 수있는 걸 던져 줘!"

이제 생각해보십시오 :
당신은 당신의 친구가 던지기로 선택하는 것을 정확히 지정하지 않았습니다 .
...하지만 다음과 같은 경우에는 중요하지 않습니다.

  • 그것은의 뭔가 수 있습니다 던져 수 (그는 당신에게 소파를 던져 수 없습니다)

  • 잡을 수있는 것 (수리검을 던지지 않았 으면 좋겠어)

  • 좀비의 두뇌를 쫓아내는 데 사용할 수있는 것입니다 (베개 등을 배제합니다)

야구 방망이를 얻든 망치를 얻든 상관 없습니다.
세 가지 조건을 충족하는 한 당신은 좋습니다.

그것을 요 ​​약하기:

인터페이스를 작성할 때 기본적으로 "나는 무언가가 필요해 ..."라고 말합니다.


13
사실 베개는 여전히 작동합니다. 그것으로 좀비를 칠 수 있습니다. 좀비의 두뇌를 박살 내십시오 ... 음 그것은 성능의 문제이며, 인터페이스의 일부가 아닙니다.
meustrus

35

인터페이스는 구현 자인지 사용자인지에 따라 준수하거나 제공해야하는 계약입니다.


1
계약은 종종 의미론이나 동작 (계약 별 설계에서와 같이)을 암시하기 때문에 여기에서 규정되지 않은 기간 계약이 마음에 들지 않습니다. 모든 인터페이스가 의미 나 동작을 의미하는 것은 아닙니다. 예를 들어, "벽의 구멍"은 실제 인터페이스입니다. 이것을 창문으로 인식하든, 쓰레기 처리로 인식하든, 아니면 다른 것으로 인식하든간에 당신의 해석입니다.
Uri

3
진실. 인터페이스는 "메서드 서명 계약"으로, 주어진 메서드를 구현하도록 보장합니다. 주어진 방식으로 그렇게하는지에 대해서는 보장하지 않습니다.
Erik Funkenbusch

정확히이 정의에 대해 더 많은 설명을해야합니다. 그러나 인터페이스는 두 부분 간의 계약입니다. 계약에 의한 코드 .... +1
matiasnj 2011-08-24

18

나는 "청사진"이 사용하기에 좋은 단어라고 생각하지 않는다. 청사진은 무언가를 만드는 방법을 알려줍니다. 인터페이스는 특히 무언가를 만드는 방법을 알려주지 않습니다.

인터페이스는 클래스와 상호 작용할 수있는 방법, 즉 지원하는 메서드를 정의합니다.


1
나는 요청자가 정의가 아닌 것이 아닌 정의가 무엇인지 물었다 고 생각합니다. :)
Eugene Kuleshov

7

나에게 인터페이스는 클래스의 청사진입니다. 이것이 가장 좋은 정의입니까?

아니요. 청사진에는 일반적으로 내부가 포함됩니다. 그러나 인터페이스는 순전히 클래스 외부에서 볼 수있는 것에 관한 것입니다. 더 정확하게는 인터페이스를 구현하는 클래스 패밀리입니다.

인터페이스는 메서드의 시그니처와 상수 값, 그리고 인터페이스를 구현하는 클래스와이를 사용하는 다른 클래스 간의 (일반적으로 비공식적 인) "동작 계약"으로 구성됩니다.


6

프로그래밍에서 인터페이스는 객체가 가질 동작을 정의하지만 실제로 동작을 지정하지는 않습니다. 특정 클래스가 무언가를 할 수 있다는 것을 보증하는 계약입니다.

여기에서이 C # 코드를 고려하십시오.

using System;

public interface IGenerate
{
    int Generate();
}

// Dependencies
public class KnownNumber : IGenerate
{
    public int Generate() 
    {
        return 5;
    }   
}

public class SecretNumber : IGenerate
{
    public int Generate()
    {
        return new Random().Next(0, 10);
    }
}

// What you care about
class Game
{
    public Game(IGenerate generator) 
    {
        Console.WriteLine(generator.Generate())
    }
}

new Game(new SecretNumber());
new Game(new KnownNumber());

Game 클래스에는 비밀 번호가 필요합니다. 이를 테스트하기 위해 비밀 번호로 사용되는 것을 주입하려고합니다 (이 원칙을 Inversion of Control이라고 함).

게임 클래스는 실제로 난수를 생성하는 것에 대해 "열린 마음"을 갖기를 원하므로 생성자에서 "Generate 메서드가있는 모든 것"을 요청합니다.

먼저 인터페이스는 객체가 제공 할 작업을 지정합니다. 그것은 단지 그것이 어떻게 생겼는지 포함하지만 실제 구현은 제공되지 않습니다. 이것은 메소드의 서명일뿐입니다. 일반적으로 C # 인터페이스에는 I 접두사가 붙습니다. 이제 클래스는 IGenerate 인터페이스를 구현합니다. 즉, 컴파일러는 둘 다 int를 반환하고 호출되는 메서드가 있는지 확인합니다 Generate. 이 게임은 이제 두 개의 다른 객체라고 불리며, 각각은 올바른 인터페이스를 구현합니다. 다른 클래스는 코드를 빌드 할 때 오류를 생성합니다.

여기서 나는 당신이 사용한 청사진 비유를 발견했습니다.

클래스는 일반적으로 객체의 청사진으로 간주됩니다. 인터페이스는 클래스가 수행해야하는 작업을 지정하므로 실제로 클래스에 대한 청사진이라고 주장 할 수 있지만 클래스에는 반드시 인터페이스가 필요하지 않기 때문에이 은유가 깨지고 있다고 주장합니다. 인터페이스를 계약이라고 생각하십시오. "서명"하는 클래스는 계약의 조건을 준수하기 위해 법적으로 요구됩니다 (컴파일러 경찰에 의해 시행됨). 이것은 인터페이스에 지정된 것을 수행해야 함을 의미합니다.

이는 Java 또는 C #의 경우처럼 일부 OO 언어의 정적으로 형식화 된 특성 때문입니다. 반면에 Python에서는 다른 메커니즘이 사용됩니다.

import random

# Dependencies
class KnownNumber(object):
    def generate(self):
        return 5

class SecretNumber(object):
    def generate(self):
        return random.randint(0,10)

# What you care about
class SecretGame(object):
    def __init__(self, number_generator):
        number = number_generator.generate()
        print number

여기서 어떤 클래스도 인터페이스를 구현하지 않습니다. 파이썬은 그것에 대해 신경 쓰지 않습니다.SecretGame 클래스는 전달 된 객체를 호출하려고 할 것입니다. 객체가 generate () 메소드를 가지고 있다면, 모든 것이 정상입니다. 그렇지 않은 경우 : KAPUTT! 이 실수는 컴파일 타임이 아니라 런타임에 발생하므로 프로그램이 이미 배포되어 실행 중일 수 있습니다. C #은 당신이 그것에 가까워지기 전에 당신에게 알려줄 것입니다.

이 메커니즘이 사용되는 이유는 OO 언어에서 자연스럽게 기능이 일류 시민이 아니기 때문입니다. 당신이 볼, 수 있듯이 KnownNumberSecretNumber숫자를 생성하는 JUST 기능이 포함되어 있습니다. 하나는 수업이 전혀 필요하지 않습니다. 따라서 파이썬에서는 그냥 버리고 스스로 함수를 선택할 수 있습니다.

# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())

# Functional Approach

# Dependencies
class SecretGame(object):
    def __init__(self, generate):
        number =  generate()
        print number

SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)

람다는 "한 줄로"선언 된 함수일뿐입니다. 대리자는 C #에서 동일합니다.

class Game
{
    public Game(Func<int> generate) 
    {
        Console.WriteLine(generate())
    }
}    

new Game(() => 5);
new Game(() => new Random().Next(0, 10));

참고 : 후자의 예는 Java 7까지 이와 같이 불가능했습니다. 여기서 인터페이스는이 동작을 지정하는 유일한 방법이었습니다. 그러나 Java 8에는 람다식이 도입되었으므로 C # 예제를 매우 쉽게 Java로 변환 할 수 있습니다 ( Func<int>java.util.function.IntSupplier되고 =>가 됨 ->).


4

기술적으로는 인터페이스를 개체와 상호 작용하는 일련의 방법 (메서드, 속성, 접근 자 ... 어휘는 사용중인 언어에 따라 다름)으로 설명합니다. 객체가 인터페이스를 지원 / 구현하는 경우 인터페이스에 지정된 모든 방법을 사용하여이 객체와 상호 작용할 수 있습니다.

의미 적으로 인터페이스는 또한 수행 할 수있는 작업 (예 : 메소드를 호출 할 수있는 순서)에 대한 규칙과 그에 대한 대가로 사용자가 상호 작용하는 방식에 따라 객체의 상태에 대해 가정 할 수있는 것에 대한 규칙을 포함 할 수 있습니다. 멀리.


2

개인적으로 나는 템플릿과 같은 인터페이스를 봅니다. 인터페이스에 foo () 및 bar () 메서드에 대한 정의가 포함되어 있으면이 인터페이스를 사용하는 모든 클래스에 foo () 및 bar () 메서드가 있음을 알고 있습니다.


2

사람 (사용자 또는 개체)이 어떤 작업을 수행하기를 원한다고 생각해 보겠습니다. 그는 회사와 계약을 맺을 중개자 (인터페이스) (구현 된 클래스를 사용하여 생성 된 실제 객체)에게 연락합니다. 어떤 회사가 그에게 결과를 제공하고 구현할 것인지 그에 의해 정의되는 작업 유형은 거의 없습니다. 모든 회사는 각자의 방식으로 작업을 구현하지만 결과는 동일합니다. 이처럼 사용자는 단일 인터페이스를 사용하여 작업을 완료합니다. 인터페이스는 내부 하위 시스템을 구현하여 내부적으로 정의되는 명령이 거의없는 시스템의 가시적 인 부분으로 작동 할 것이라고 생각합니다.


1

인터페이스는 클래스의 작업을 내부 구현과 분리합니다. 따라서 일부 구현은 많은 인터페이스를 제공 할 수 있습니다.

사람들은 일반적으로 클래스의 메서드에서 사용할 수 있어야하는 것에 대한 "계약"이라고 설명합니다.

그것은 구현을 결정하기 때문에 절대 청사진이 아닙니다. 전체 클래스 정의는 청사진이라고 할 수 있습니다.


1

인터페이스는 상속 된 클래스가 구현해야하는 것을 정의합니다. 이러한 방식으로 여러 클래스가 인터페이스에서 상속 할 수 있으며 이러한 상속으로 인해 다음을 수행 할 수 있습니다.

  • 인터페이스의 모든 멤버가 파생 클래스에서 구현되었는지 확인하십시오 (예외를 던지는 경우에도).
  • 호출자로부터 클래스 자체를 추상화합니다 (클래스의 인스턴스를 인터페이스로 캐스팅하고 실제 파생 클래스가 무엇인지 알 필요없이 상호 작용)

자세한 내용은 http://msdn.microsoft.com/en-us/library/ms173156.aspx를 참조하십시오 .


1

제 생각에 인터페이스는 Java에서 일반적으로 관련된 것보다 더 넓은 의미를 가지고 있습니다. "인터페이스"는 모듈을 제어 / 모니터링 할 수있는 몇 가지 공통 기능이있는 사용 가능한 작업 집합으로 정의합니다.

이 정의에서는 클라이언트가 일부 모듈 인 프로그래밍 인터페이스와 휴먼 인터페이스 (예 : GUI)를 모두 다루려고합니다.

다른 사람들이 이미 말했듯이 인터페이스는 입력 및 출력 측면에서 항상 약간의 계약이 있습니다. 인터페이스는 작업의 "방법"에 대해 아무것도 약속하지 않습니다. 현재 상태, 선택한 작업 및 해당 매개 변수가 주어지면 결과의 일부 속성 만 보장합니다.


1

위와 같이 "contract"와 "protocol"의 동의어가 적절합니다.

인터페이스는 클래스에 의해 노출 될 것으로 예상 할 수있는 메서드와 속성으로 구성됩니다.

따라서 클래스 Cheetos BagChip Bag인터페이스를 구현하는 Cheetos Bag경우 다른 Chip Bag. (즉, .attemptToOpenWithoutSpillingEverywhere()메소드 노출 등)


1

기존 정의-인터페이스는 구현하는 클래스가 구현해야하는 메소드를 지정하는 계약입니다.

인터페이스의 정의는 시간이 지남에 따라 변경되었습니다. 인터페이스에 메서드 선언 만 있다고 생각하십니까? 정적 최종 변수와 Java 5 이후의 기본 정의는 어떻습니까?

다중 상속에 대한 Diamond 문제 때문에 Java에 인터페이스가 도입되었으며 실제로 그렇게하려고합니다.

인터페이스는 다중 상속 문제를 해결하기 위해 생성 된 구조이며 추상 메서드, 기본 정의 및 정적 최종 변수를 가질 수 있습니다.

http://www.quora.com/Why-does-Java-allow-static-final-variables-in-interfaces-when-they-are-only-intended-to-be-contracts



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