좋아, 내 친구가 프로그래밍에서 "인터페이스"가 의미하는 바를 앞뒤로 이동합니다.
"인터페이스"에 대한 가장 좋은 설명은 무엇입니까?
나에게 인터페이스는 클래스의 청사진입니다. 이것이 가장 좋은 정의입니까?
좋아, 내 친구가 프로그래밍에서 "인터페이스"가 의미하는 바를 앞뒤로 이동합니다.
"인터페이스"에 대한 가장 좋은 설명은 무엇입니까?
나에게 인터페이스는 클래스의 청사진입니다. 이것이 가장 좋은 정의입니까?
답변:
인터페이스는 개발 과정에서 과부하되고 혼란스러운 용어 중 하나입니다.
실제로 추상화와 캡슐화의 개념입니다. 주어진 "상자"에 대해 해당 상자 의 "입력"및 "출력"을 선언 합니다. 소프트웨어 세계에서 이는 일반적으로 상자에서 (인수와 함께) 호출 할 수있는 작업과 경우에 따라 이러한 작업의 반환 유형을 의미합니다.
이것이하지 않는 것은 이러한 연산의 의미가 무엇인지 정의하는 것입니다. 그러나 선언에 근접하여 (예 : 주석을 통해) 문서화하거나 좋은 명명 규칙을 선택하는 것이 일반적이고 (매우 좋은 관행)이지만. 그럼에도 불구하고 이러한 의도를 따를 것이라는 보장은 없습니다.
비유는 다음과 같습니다. TV가 꺼져있을 때 TV를 살펴보십시오. 인터페이스는 버튼, 다양한 플러그 및 화면입니다. 의미와 동작은 입력 (예 : 케이블 프로그래밍)을 받고 출력 (화면 표시, 사운드 등)을 갖는다는 것입니다. 그러나 연결되지 않은 TV를 보면 예상되는 의미를 인터페이스에 투영하는 것입니다. 아시다시피 TV를 꽂으면 폭발 할 수 있습니다. 그러나 "인터페이스"를 기반으로하면 물을 마시지 않기 때문에 커피를 만들지 않을 것이라고 가정 할 수 있습니다.
객체 지향 프로그래밍에서 인터페이스는 일반적으로 해당 인터페이스가있는 클래스의 인스턴스가 응답 할 수있는 메서드 (또는 메시지) 집합을 정의합니다.
혼란을 더하는 것은 Java와 같은 일부 언어에는 언어 별 의미 체계를 가진 실제 인터페이스가 있다는 것입니다. 예를 들어 Java에서는 구현이없는 메서드 선언 집합이지만 인터페이스도 유형에 해당하고 다양한 입력 규칙을 따릅니다.
C ++와 같은 다른 언어에서는 인터페이스가 없습니다. 클래스 자체는 메서드를 정의하지만 클래스의 인터페이스를 비공개 메서드의 선언으로 생각할 수 있습니다. C ++ 컴파일 방식으로 인해 실제 구현없이 클래스의 "인터페이스"를 가질 수있는 헤더 파일을 얻을 수 있습니다. 순수 가상 함수 등을 사용하여 추상 클래스로 Java 인터페이스를 모방 할 수도 있습니다.
인터페이스는 확실히 클래스의 청사진이 아닙니다. 하나의 정의에 따르면 청사진은 "상세한 행동 계획"입니다. 인터페이스는 행동에 대해 아무것도 약속하지 않습니다! 혼란의 원인은 대부분의 언어에서 일련의 메소드를 정의하는 인터페이스 유형이있는 경우이를 구현하는 클래스가 동일한 메소드를 "반복"하므로 (정의를 제공함) 인터페이스가 골격 또는 수업 개요.
다음 상황을 고려하십시오.
좀비가 갑자기 당신을 공격 할 때 당신은 크고 빈 방 한가운데에 있습니다.
무기가 없습니다.
운 좋게도, 살아있는 동료가 방의 출입구에 서 있습니다.
"빨리!" 당신은 그에게 소리 친다. "좀비를 때릴 수있는 걸 던져 줘!"
이제 생각해보십시오 :
당신은 당신의 친구가 던지기로 선택하는 것을 정확히 지정하지 않았습니다 .
...하지만 다음과 같은 경우에는 중요하지 않습니다.
그것은의 뭔가 수 있습니다 던져 수 (그는 당신에게 소파를 던져 수 없습니다)
잡을 수있는 것 (수리검을 던지지 않았 으면 좋겠어)
좀비의 두뇌를 쫓아내는 데 사용할 수있는 것입니다 (베개 등을 배제합니다)
야구 방망이를 얻든 망치를 얻든 상관 없습니다.
세 가지 조건을 충족하는 한 당신은 좋습니다.
그것을 요 약하기:
인터페이스를 작성할 때 기본적으로 "나는 무언가가 필요해 ..."라고 말합니다.
인터페이스는 구현 자인지 사용자인지에 따라 준수하거나 제공해야하는 계약입니다.
나는 "청사진"이 사용하기에 좋은 단어라고 생각하지 않는다. 청사진은 무언가를 만드는 방법을 알려줍니다. 인터페이스는 특히 무언가를 만드는 방법을 알려주지 않습니다.
인터페이스는 클래스와 상호 작용할 수있는 방법, 즉 지원하는 메서드를 정의합니다.
프로그래밍에서 인터페이스는 객체가 가질 동작을 정의하지만 실제로 동작을 지정하지는 않습니다. 특정 클래스가 무언가를 할 수 있다는 것을 보증하는 계약입니다.
여기에서이 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 언어에서 자연스럽게 기능이 일류 시민이 아니기 때문입니다. 당신이 볼, 수 있듯이 KnownNumber
및 SecretNumber
숫자를 생성하는 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
되고 =>
가 됨 ->
).
사람 (사용자 또는 개체)이 어떤 작업을 수행하기를 원한다고 생각해 보겠습니다. 그는 회사와 계약을 맺을 중개자 (인터페이스) (구현 된 클래스를 사용하여 생성 된 실제 객체)에게 연락합니다. 어떤 회사가 그에게 결과를 제공하고 구현할 것인지 그에 의해 정의되는 작업 유형은 거의 없습니다. 모든 회사는 각자의 방식으로 작업을 구현하지만 결과는 동일합니다. 이처럼 사용자는 단일 인터페이스를 사용하여 작업을 완료합니다. 인터페이스는 내부 하위 시스템을 구현하여 내부적으로 정의되는 명령이 거의없는 시스템의 가시적 인 부분으로 작동 할 것이라고 생각합니다.
인터페이스는 상속 된 클래스가 구현해야하는 것을 정의합니다. 이러한 방식으로 여러 클래스가 인터페이스에서 상속 할 수 있으며 이러한 상속으로 인해 다음을 수행 할 수 있습니다.
자세한 내용은 http://msdn.microsoft.com/en-us/library/ms173156.aspx를 참조하십시오 .
제 생각에 인터페이스는 Java에서 일반적으로 관련된 것보다 더 넓은 의미를 가지고 있습니다. "인터페이스"는 모듈을 제어 / 모니터링 할 수있는 몇 가지 공통 기능이있는 사용 가능한 작업 집합으로 정의합니다.
이 정의에서는 클라이언트가 일부 모듈 인 프로그래밍 인터페이스와 휴먼 인터페이스 (예 : GUI)를 모두 다루려고합니다.
다른 사람들이 이미 말했듯이 인터페이스는 입력 및 출력 측면에서 항상 약간의 계약이 있습니다. 인터페이스는 작업의 "방법"에 대해 아무것도 약속하지 않습니다. 현재 상태, 선택한 작업 및 해당 매개 변수가 주어지면 결과의 일부 속성 만 보장합니다.
위와 같이 "contract"와 "protocol"의 동의어가 적절합니다.
인터페이스는 클래스에 의해 노출 될 것으로 예상 할 수있는 메서드와 속성으로 구성됩니다.
따라서 클래스 Cheetos Bag
가 Chip Bag
인터페이스를 구현하는 Cheetos Bag
경우 다른 Chip Bag
. (즉, .attemptToOpenWithoutSpillingEverywhere()
메소드 노출 등)
기존 정의-인터페이스는 구현하는 클래스가 구현해야하는 메소드를 지정하는 계약입니다.
인터페이스의 정의는 시간이 지남에 따라 변경되었습니다. 인터페이스에 메서드 선언 만 있다고 생각하십니까? 정적 최종 변수와 Java 5 이후의 기본 정의는 어떻습니까?
다중 상속에 대한 Diamond 문제 때문에 Java에 인터페이스가 도입되었으며 실제로 그렇게하려고합니다.
인터페이스는 다중 상속 문제를 해결하기 위해 생성 된 구조이며 추상 메서드, 기본 정의 및 정적 최종 변수를 가질 수 있습니다.
인터페이스는 일부 OO 언어가 ad hoc 다형성을 달성하는 방법 입니다. Ad Hoc 다형성은 단순히 다른 유형에서 작동하는 동일한 이름을 가진 함수입니다.
요컨대, 인터페이스가 해결하려는 기본적인 문제는 우리가 무언가를 사용하는 방식과 구현 방식을 분리하는 것입니다. 그러나 인터페이스 는 계약이 아니라는 점을 고려해야 합니다. 여기에서 자세한 내용을 읽어보십시오 .