2016-07-13 5 views
0

인터페이스를 정의하고 기본 추상 클래스에 인터페이스를 구현하고 기본 동작을 부여한 다음 기본 클래스에서 상속하는 것이 좋습니까?인터페이스 및 기본 추상 클래스 C#

아니면 잔인합니까?

+0

당신이 달성하려고하는 것에 달려 있습니다 ... 인터페이스는 모든 코드를 수정하지 않고 구현을 변경할 수 있도록 계약서를 릴레이 할 수있는 기능을 제공합니다. 기본 클래스는 기본 동작을 설명하는 데 유용합니다. – Thomas

답변

4

인터페이스 또는 추상 클래스를 사용할지 여부는 완전히 다른 두 가지 질문입니다. 두 가지에 대한 대답이 이지만 다른 하나와 아무 관계가 없을 수도 있습니다.

기본 클래스에서 상속 받고 특정 메서드를 공유하는 여러 클래스가 필요할 것이라는 확신이 확실하지 않은 경우 상속을 사용하려고 미리 계획하지 않습니다. 우리가 완벽한 교과서 클래스 계층 구조를 구상하기 시작하면 종종 복잡해지며 잘 풀리지 않습니다. 리팩토링 할 때나 비슷한 클래스를 작성하고 코드를 복제하고 싶지 않은 경우에 더 자주 사용됩니다.

인터페이스를 작성한 다음이를 구현하는 것은 다른 클래스가 의존하는 (매우 자주 사용되는) 것을 만들 때 좋은 방법입니다. 예를 들어, 클래스가 의존 할 것이라는 것을 알고 있다면 "무언가를하는 또 다른 클래스"는 IDoesSomething 인터페이스를 작성하고 첫 번째 클래스에서 작업을 잠시 멈추고 IDoesSomething에 의존하는 첫 번째 클래스를 마칠 수 있습니다. 구현이 아직 무엇인지 알 수는 없지만, 이미 작성중인 클래스가 인터페이스에만 의존하기 때문에 중요하지 않습니다. (Inversion of Control - 좋은 연습.) 그러면 IDoesSomething을 구현하는 클래스를 작성할 수 있습니다.

예를 들어 설명해 드리겠습니다. 내가 MenuItem 개체의 중첩 된 목록을 포함하는 Menu 개체를 제공하는 클래스를 쓰고 있어요 가정 :

public class MenuProvider 
{ 
    public Menu GetMenu(string menuId) 
    { 
     //code that gets the menu 
     return menu; 
    } 
} 

그럼 내가 그것을 반환하기 전에 특정 메뉴 항목을 필터링 할 필요 해요 실현. 이는 구성 설정, 특정 사용자 또는 다른 어떤 것을 기반으로 할 수 있습니다.

public interface IMenuFilter 
{ 
    void FilterMenu(Menu menu); 
} 

를 다음과 같이 내 원래의 클래스를 수정 :

나는이 인터페이스를 작성할 수 있습니다 내가 IMenuFilter의 구현이 될 것입니다 모르는

public class MenuProvider 
{ 
    private readonly IMenuFilter _menuFilter; 

    public MenuProvider(IMenuFilter menuFilter) 
    { 
     _menuFilter = menuFilter; 
    } 

    public Menu GetMenu(string menuId) 
    { 
     //code that gets the menu 

     //filter the menu 
     _menuFilter.FilterMenu(menu); 
     return menu; 
    } 
} 

. 실제로는 한 가지 유형의 필터링을 수행하는 여러 클래스의 복합체가 될 수도 있습니다.그러나 요점은 내가 이것을 이해하기 위해 내가 수행하고있는 것을 막을 필요가 없다는 것이다. 이 클래스를 작성하고 심지어 조롱 된 IMenuFilter으로 테스트 한 다음 해당 필터의 특성을 작성하는 단계로 넘어갈 수 있습니다.

+0

답장을 보내 주셔서 감사합니다! – MaitlandMarshall

2

이 인터페이스의 구현간에 공유 할 공통 기능이 있습니까? 그렇다면 추상 기본 클래스를 작성하십시오. 그렇지 않으면 지금은 걱정하지 마십시오. 나중에 언제든지 추가 할 수 있습니다. 그러나 인터페이스 프로그래밍은 항상 좋은 생각입니다.

1

일반적으로 인터페이스 또는 상속을 사용합니다. 나는 보통 같은 수업에서 둘 다 사용하지 않는다.

기본 클래스에서 기능을 상속하려면 상속을 사용하십시오.

이기종 클래스가 동일한 핵심 기능을 구현하고 코드를 반드시 공유하지 않을 때 인터페이스를 사용하십시오.

+2

개인적으로 동의하지 않습니다. 충분히 복잡한 시나리오에서 인터페이스에 대한 소비자 코드를 작성하고 구체적인 기본 구현의 DRY를 유지하는 추상 기본 클래스의 계층 구조를 유지하는 것이 합리적이라고 생각합니다. –

+0

실제 예제 : 소프트웨어는 'IOutputController'의 추상화가 아닌 구현에 대해 리플렉션을 사용하여 플러그인 어셈블리를 쿼리합니다. 플러그인 (주 응용 프로그램이 아닌 다른 사람이 작성)은이 인터페이스를 구현합니다. 그들은'OutputControllerBase','SerialOutputControllerBase' 또는'ParallelOutputControllerBase'와 같은 다양한 ABC로부터 상속받을 수 있습니다. 이들은 메인 앱에서 제공됩니다. 그러나, 그들은 단지'IOutputController'를 구현해야하기 때문에 그것들 중 아무 것도 상속받을 필요가 없습니다. –

+1

나는 또한 이것에 동의하지 않는다. 우리가 추상적 인 클래스와 인터페이스를 일반적으로 사용하지 않을 것을 제안하는 것은 하나가 다른 것과 관련이 있음을 암시한다. 인터페이스는 계약을 구현과 분리합니다. 그렇다면 왜 추상 클래스를 포함하는 구현이 * 유일한 구현이라고 기대할 수 있을까요? 우리는 여러 구현물을 가진 인터페이스를 자주 가질 수 있으며 일부는 추상 클래스를 포함합니다. 또한 인터페이스는 클래스 공유 기능과는 아무런 관련이 없습니다. 공통 기능이없는 구현을 가능하게합니다. –

관련 문제