C # : 추상 클래스는 인터페이스를 구현해야합니까?


131

C #의 테스트 코드 :

namespace DSnA
{
    public abstract class Test : IComparable
    {

    }
}

다음과 같은 컴파일러 오류가 발생합니다.

error CS0535: 'DSnA.Test' does not implement interface member
'System.IComparable.CompareTo(object)'

클래스 Test추상 클래스 이기 때문에 왜 컴파일러가 인터페이스를 구현하기 위해 클래스를 요구합니까? 이 요구 사항이 구체적인 수업에 대해서만 의무적 이지 않아야 합니까?


ㅋ. 나는 한 가지를 썼고 그것을 바꾸기로 결정했다. 죄송합니다. :)
Joel

2
downvotes와 허용 된 답변에 대한 의견을 바탕으로, downvotes는 질문이 표현 된 방식으로 온다고 생각합니다. OP는 "이런 이유는 무엇입니까?"라고 묻습니다. 이 문제를 직접 겪은 문제는 "무엇이 누락 되었습니까? 구현을 실제로 제공해야합니까? 그것이 추상 클래스라는 점을 깨뜨리지 않습니까?"입니다. 대답은 "아니요 . 추상 클래스의 목적을 위반하는 구현 을 제공 할 필요는 없지만 상황을 작동시키기 위해해야 ​​할 일이 있습니다."
ToolmakerSteve

구현을 제공 해야하는 경우를 발견했습니다. 인터페이스에 선택적 매개 변수가 있습니다. 기본 클래스에 메소드를 abstract로 포함하면 상속 된 클래스는 선택적 매개 변수없이 컴파일되지 않습니다 (선택적 매개 변수의 목적을 상실 함). 이 경우에는 NotImplementedException을 던집니다.
Paul McCarthy

내 이전 의견을 무시하십시오-예상대로 작동하지 않았으며 최소 놀람의 원칙은 여기에 적용되지 않습니다.
Paul McCarthy

답변:


141

C #에서 인터페이스를 구현하는 클래스 는 해당 인터페이스의 모든 멤버를 정의 해야 합니다. 추상 클래스의 경우 abstract키워드를 사용하여 해당 멤버를 정의하면됩니다 .

interface IFoo
{
    void Bar();
}

abstract class Foo : IFoo
{
    public abstract void Bar();
}

아니면 다른 방법을 넣어 : 당신이 하지 에있다 "구현" (추상 클래스에 끔찍한 제한 될 것이다) 그; 그러나 C #에서는 컴파일러에게 의도적으로 벅을 구체적인 서브 클래스로 전달한다고 알려 주어야합니다. 위의 코드 행은 그렇게하는 방법을 보여줍니다.

이것이 질문에 대한 답변이 아니라고 불평하는 의견과 공감대는 요점이 없습니다. 누군가가 스택 오버플로에 와서이 컴파일러 오류를 받았지만 구현을 제공하는 데 실수가되는 추상 클래스가 있으면 좋은 해결책없이 고착됩니다. 런타임 예외를 발생시키는 구현 방법을 작성해야합니다. 끔찍한 작업 -약속-위의 정보를 얻을 때까지 C #에서 이러한 명시 성을 요구하는 것이 좋든 나쁘 든 스택 오버플로의 범위를 벗어나며 질문이나 대답과 관련이 없습니다.


2
@Ben 방금 댓글을 보았습니다. 당신은 아마 그것을 이미 알아 냈을 수도 있지만 다른 누군가가 그것을 필요로 할 경우를 대비하여. 명시 적 인터페이스 구현 확인 : msdn.microsoft.com/en-us/library/ms173157.aspx
Joel

2
@Joel @Ben 명시 적 인터페이스가 추상 클래스와 작동 할 수 있다고 생각하지 않습니다. 위의 예제 코드에서 정의를 Foo로 변경하면 public abstract void IFoo.Bar();"public"및 "abstract"가 유효한 수정자가 아니라는 불만이 표시됩니다.
대런 쿡

8
이것은 이것이 추상 클래스이고 컴파일러가 공백을 채우는 방법을 알아야한다는 것을 고려할 때 이것이 왜 필요한지에 대한 질문에는 대답하지 않습니다. Java에서는 필요하지 않으므로 ioc 컨테이너의 데코레이터 패턴 (예 : Spring / JavaEE) (관리되는 인터페이스의 특정 방법을 장식해야하는 경우)과 같은 몇 가지 유용한 패턴을 사용할 수 있습니다. 동일한 in.net 구현은 개발자가 특히 nhibernate의 ISession과 같은 큰 인터페이스에 대해 매우 장황하게 만들어야 할 것입니다
Sheepy

1
AspectJ의 믹스 인이 또 다른 예입니다. 많은 추상 클래스의 부분 구현을 단일 인터페이스로 혼합 할 수 있습니다. 각 추상 클래스는 구현하려는 메소드 만 구현하면됩니다. 내가 .net에서 동일한 기능을 재현하려는 경우와 같이 멍청한 추상 방법 상용구가
막히지 않습니다

1
@Sheepy-사실, 그러나 IMHO, 당신 은 asker가 필요 로하는 것과 이것이 어떻게 "답변" 인지 오해 합니다 . 나도 같은 질문을했다. 구현을 제공하는 것이 필요하지 않기 때문에 나는 붙어 있었다. 답은 " 구현 "할 필요는 없습니다. 그러나 컴파일러에게 구현하지 않겠다고 알려주기 위해해야일이 있습니다. (당신이 [정확하게] 이것이 답이 아니라고 말하는 질문은 적절한 stackoverflow 질문이 아닐 것입니다-그것은 단순히 목적이 아닌 것으로 닫 혔을 것입니다.)
ToolmakerSteve

10

Java와는 달리 C #에서 : "추상 클래스는 클래스의 기본 클래스 목록에 나열된 모든 인터페이스 멤버의 구현을 제공해야하지만 추상 클래스는 인터페이스 메소드를 추상 메소드에 맵핑 할 수 있습니다."

https://msdn.microsoft.com/en-us/library/Aa664595(v=VS.71).aspx


1
때로는 기본 클래스에서 동작을 구현하고 싶을 수도 있으므로 두 가지 상황을 모두 제공하는 매우 명확한 대답과 훌륭한 답변
VinKel

여기서 발생하는 한 가지 질문은 다음과 같습니다. 왜 이러한 C # 상용구 선언 (명확하게)이 추상 클래스에 존재해야합니까? 내 C # 프로젝트에는 많은 추상 클래스와 인터페이스가 있으며 대부분 Visual Studio에서 메서드 선언을 복사하여 붙여 넣는 작업을 수행합니다.
forsberg

5

실제로 인터페이스를 구현할 필요는 없습니다 .
인터페이스 방법 / 속성은 추상적이거나 가상적 일 수도 있습니다. 따라서 실제로 구현하기 위해 서브 클래스에 달려 있습니다.

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