2012-04-26 3 views
4

인터페이스와 추상의 차이점을 이해한다고 생각합니다. 초록은 기본 비헤이비어를 설정하고 순수 초록의 경우 비헤이비어를 통해 비헤이비어를 설정해야합니다. 인터페이스는 기본 클래스의 오버 헤드없이 필요한 것을 가져옵니다. 그렇다면 구성에 비해 인터페이스의 이점은 무엇입니까? 내가 생각할 수있는 유일한 장점은 기본 클래스에서 보호 된 필드를 사용하는 것입니다. 내가 뭘 놓치고 있니?인터페이스와 컴포지션

+2

어떤 언어를 고려하십니까?/ –

답변

3

인터페이스는 사용자의 사용 방법을 정의합니다.

재사용을 위해 상속합니다. 즉, 일부 프레임 워크에 적합하길 원합니다. 프레임 워크에 맞출 필요가 없다면, 심지어 자신의 제작 중 하나라도 상속하지 마십시오.

구성은 구현 세부 사항입니다. 기본 클래스의 구현을 얻으려면 상속하지 말고 작성하십시오. 프레임 워크에 맞출 수있는 경우에만 상속받습니다.

5

인터페이스 동작을 정의합니다. 추상 클래스는 동작을 구현하는 데 유용합니다.

이론상 전혀 구현이없는 추상 클래스 인 과 인터페이스 사이에는 많은 차이가 없습니다. 두 함수 모두 구현되지 않은 API를 정의합니다. 그러나 순수 추상 클래스는 인터페이스 (예 : C++)를 제공하는 인터페이스를 지원하지 않는 언어에서 자주 사용됩니다.

선택 사항이있는 경우 일반적으로 추상 기반은 완료되지 않은 경우에도 일정 수준의 기능을 제공합니다. 공통된 행동을 구현하는 데 도움이됩니다. 단점은 당신이 그것으로부터 파생하도록 강요 당한다는 것입니다. 단순히 사용법을 정의 할 때는 인터페이스를 사용하십시오. 인터페이스를 구현하는 추상 기반을 만드는 것을 막을 수있는 방법은 없습니다.

0

인터페이스는 C++에서 순수한 가상 함수 만있는 클래스로 설명 할 수 있습니다.

  • 은 그것이 사용자와 인터페이스의 구현 사이의 결합 (의존성)를 줄여 인터페이스
  • 를 사용하여 또는 구현의 학습 곡선이 감소하기 때문에 얇은 좋다. 따라서 사용자는 자신이 사용하고있는 인터페이스 구현의 변경 사항으로부터 실제로 격리되어 있습니다.

이는 동적 라이브러리 링크와 함께, 플러그를 촉진하고, 최근의 알려지지하지만 위대한 소프트웨어 혁신 중 하나를 재생하는 데 도움이됩니다. 이로 인해 소프트웨어 상호 운용성, 확장 성 등이 향상됩니다.

인터페이스는 더 많은 작업을 수행 할 수 있습니다. 언젠가 가능한 구현을 한 번 이상 가질 수있는 중요한 하위 시스템을 가지고있을 때 채택을 정당화하십시오. 이 경우 서브 시스템은 인터페이스를 통해 사용해야합니다.

inheiritance를 통한 재사용은 오버라이드중인 구현의 동작에 대한 더 많은 지식을 필요로하므로 더 큰 "결합"이 있습니다. 이는 인터페이스가 과도하게 사용되는 경우에도 유효한 접근 방법이라고 말했습니다.

+0

Interface vs Composition의 특정 컨텍스트에서 인터페이스는 composition보다 * more * coupling을 도입합니다. –

+0

나는 그것을 보지 않는다. 정교하게 자유롭게 해주세요. – ScrollerBlaster

+1

문제는 상속 동작입니다. 문제는 상속이 외부에서 볼 수 있으므로 다른 사람이 상속을 사용하여 불필요한 결합을 유발할 수 있다는 것입니다. 반면에, 당신의 속성은 숨겨져 있기 때문에, 아무도 그들에 의존하지 않습니다. 따라서 Composition은 어떠한 결합도 가져 오지 않습니다. –

4

제목이 이해가 안되며 설명이 약간 흐릿하므로 용어를 정의하고 누락 된 부분을 소개합시다.

여기에 무슨 다른 두 가지가 있습니다

  • 추상 클래스
  • 상속 인터페이스 대 구성 대

우리가 인터페이스와 추상 클래스 시작하자가.

  • 는 (C++에서)를 추상 클래스는 적어도 하나의 방법은 순수 가상 메서드이기 때문에 인스턴스화 할 수없는 클래스입니다.
  • 은 Java와 유사한 언어로 구현되지 않은 메소드 세트이며, C++에서는 으로 에뮬레이트됩니다. 순수 클래스 만 사용하는.

그래서 C++의 맥락에서 어느쪽에도 별 차이가 없습니다. 특히이 구별은 자유 기능을 고려하지 않았기 때문에 특히 그렇습니다.

class LessThanComparable { 
public: 
    virtual ~LessThanComparable() {} 

    virtual bool less(LessThanComparable const& other) const = 0; 
}; 

당신은 하찮게도 무료 기능, 기능 보강 할 수 있습니다 :

는 예를 들어, 다음의 "인터페이스"생각이 경우

inline bool operator<(LessThanComparable const& left, LessThanComparable const& right) { 
    return left.less(right); 
} 

inline bool operator>(LessThanComparable const& left, LessThanComparable const& right) { 
    return right.less(left); 
} 

inline bool operator<=(LessThanComparable const& left, LessThanComparable const& right) { 
    return not right.less(left); 
} 

inline bool operator>=(LessThanComparable const& left, LessThanComparable const& right) { 
    return not left.less(right); 
} 

을, 우리는 아직 ... 동작을 제공 클래스 자체는 여전히 인터페이스입니다 ... 오 잘.


진짜 논쟁은, 그러므로, 상속 사이 구성입니다.

상속은 종종 행동을 상속하기 위해 오용됩니다. 이것은 나쁘다. 상속은 is-a 관계를 모델링하는 데 사용해야합니다. 그렇지 않으면 작곡을 원할 것입니다. 어떻게 우리가이 가진 Car를 구축 할 지금

class DieselEngine { public: void start(); }; 

:

은 간단한 사용 사례를 고려?

상속받은 경우 작동합니다. 그러나 갑자기 같은 코드를 얻을 :

void start(DieselEngine& e) { e.start(); } 

int main() { 
    Car car; 
    start(car); 
} 

를 이제, 당신이 WaterEngineDieselEngine를 대체하기로 결정한 경우, 위의 기능이 작동하지 않습니다. 컴파일이 실패합니다. 그리고 WaterEngine을 갖는 것이 DieselEngine에서 확실하게 느껴집니다 ...

그 해결책은 무엇입니까? 구성.

class Car { 
public: 
    void start() { engine.start(); } 

private: 
    DieselEngine engine; 
}; 

이 방법은, 아무도는 자동차 엔진 있다고 가정 무의미한 코드를 작성할 수 있습니다 (DOH를!). 따라서 엔진을 변경하면 은 쉽게고객의 영향은입니다.

이것은 구현과이를 사용하는 코드 사이의 순응성이 낮다는 것을 의미합니다. 또는 일반적으로 다음과 같이 언급됩니다 : less coupling.


일반적으로 데이터가 있거나 동작을 구현하는 클래스에서 상속하는 것은 싫은 할 것입니다. 합법적 일 수 있지만 더 좋은 방법이 있습니다. 물론, 엄지 손가락의 모든 규칙과 마찬가지로, 그것은 소금 한 알갱이로 가져 가야합니다. overengineering주의하십시오.

0

Y 유형이 X 유형을 상속하는 경우 X 유형의 객체를 처리하는 방법을 알고있는 코드는 대부분 Y 유형의 객체를 자동으로 처리 할 수 ​​있습니다. 마찬가지로 Z 유형이 인터페이스 I를 구현하면, 객체를 사용하는 방법을 알고있는 코드는 무엇이든 알지 못해도 Z 유형의 객체를 자동으로 사용할 수 있습니다. 상속과 인터페이스의 주 목적은 이러한 대체를 허용하는 것입니다.

대조적으로, P 타입의 객체가 Q 타입의 객체를 포함하면, Q 타입의 객체로 작업 할 것으로 기대되는 코드는 P가 P에서 상속받지 않는 한 P 타입 중 하나에서 작동 할 수 없습니다. 해당 유형의 객체를 보유하고 있음). Q 유형의 객체를 조작하려고하는 코드는 P 내에 포함 된 Q 인스턴스에서 작동 할 수 있지만 P 코드가 명시 적으로 해당 코드에 제공하거나 해당 코드를 외부 코드에서 사용할 수있게하는 경우에만 가능합니다.

관련 문제