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

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

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

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



답변

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

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

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

비유는 다음과 같습니다. 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 언어에서 자연스럽게 기능이 일류 시민이 아니기 때문입니다. 당신이 볼, 수 있듯이 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되고 =>가 됨 ->).


답변

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

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