C#:抽象クラスはインターフェイスを実装する必要がありますか?


131

C#でのテストコード:

namespace DSnA
{
    public abstract class Test : IComparable
    {

    }
}

次のコンパイラエラーが発生します。

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

クラスTest抽象クラスなので、コンパイラーはなぜインターフェースを実装する必要があるのですか?この要件はすべきではない強制具体的なクラスのために?


はは。私は1つのことを書いて、それを変更することにしました。ごめんなさい。:)
Joelが

2
反対票と受け入れられた回答へのコメントに基づいて、私は反対票が質問の言葉遣いのために来ると思います。OPは「なぜこのようになっているのか」と尋ねます。これは、stackoverflowの範囲外です。自分でこれに遭遇した場合、質問は「何かが足りないのか?本当に実装を提供する必要があるのか​​?それが抽象クラスであるという意味を打ち負かしていないのでは?」答えは「いいえ、抽象クラスの目的に違反する実装を提供する必要はありませんが、状況を機能させるために、ここで行う必要があることです。」
ToolmakerSteve 2017

実装を提供する必要がある場合を見つけました。これは、インターフェースにオプションのパラメーターがある場所です。メソッドを抽象として基本クラスに含めると、継承されたクラスはオプションのパラメーターなしではコンパイルされません(オプションのパラメーターの目的に反します)。この場合は、NotImplementedExceptionをスローするだけです。
ポールマッカーシー

以前のコメントは無視してください-期待どおりに動作しませんでした。ここで、驚きを最小限にするという原則は適用されません。
ポールマッカーシー

回答:


141

C#では、インターフェイスを実装するクラスは、そのインターフェイスのすべてのメンバーを定義する必要あります。抽象クラスの場合、これらのメンバーをabstractキーワードで定義するだけです。

interface IFoo
{
    void Bar();
}

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

または別の言い方をすれば、「実装」する必要はありません(抽象クラ​​スにひどい制限があります)。ただし、C#では、意図的にbuckを具象サブクラスに渡すことをコンパイラに通知する必要があり、上記のコード行はその方法を示しています。

これが質問への回答ではないことを訴えるコメントと反対票には要点が欠けています。スタックオーバーフローに来て、このコンパイラエラーを受け取ったものの、実装を提供するのは間違いである抽象クラスがある誰かが、適切な解決策なしで立ち往生している-ランタイム例外をスローする実装メソッドを記述する必要があり、恐ろしい作業-around-上記の情報が得られるまで。C#がこの明示性を要求することが良いか悪いかはスタックオーバーフローの範囲外であり、質問やこの回答には関係ありません。


2
@Benあなたのコメントを見た。あなたはおそらくすでにそれを理解していますが、誰かがそれを必要とする場合に備えて。明示的なインターフェイスの実装を確認してください
Joel

2
@Joel @Ben明示的なインターフェイスが抽象クラスで機能するとは思わない。上記のコード例では、の定義をに変更Fooするpublic abstract void IFoo.Bar();と、「public」と「abstract」は有効な修飾子ではないという不満が出ます。
ダレン・クック

8
これは抽象クラスであり、コンパイラは空白を埋める方法を知っている必要があるため、これはなぜ必要なのかという質問には答えません。Javaではこれは不要です。これにより、Spring / JavaEEなどのiocコンテナーのデコレーターパターンなどのいくつかの便利なパターンが可能になります(管理対象インターフェースの特定のメソッドを装飾する必要がある場合)。同じin.netの実装では、特にnhibernateのISession
Sheepy

1
AspectJのミックスインは別の例です。多くの抽象クラスの部分的な実装を1つのインターフェースに混在させることができます。各抽象クラスは、実装したいメソッドを実装するだけで済みます。同じ機能を.netで再作成する場合のように、ダム抽象メソッドの定型文が邪魔になることはありません
Sheepy

1
@Sheepy-本当ですが、私見、あなたは質問者が何を必要としているのか、そしてこれが実際に「答え」であることを誤解しています。私も同じ質問をしました-実装を提供するように要求されるのは意味がないので、私は行き詰まりました。あなたは:答えはありません「を持って実装することを」 -しかし、ここであなたは何であるしなければならないんあなたはそれを実装するつもりはないことをコンパイラに指示します。(これが回答ではないと[正しく]言っている質問は、適切なスタックオーバーフローの質問ではありません-単に目的外として閉じられていたでしょう。)
ToolmakerSteve

10

Javaとは異なり、C#では、「抽象クラスは、クラスの基本クラスリストにリストされているインターフェイスのすべてのメンバーの実装を提供する必要があります。ただし、抽象クラスは、インターフェイスメソッドを抽象メソッドにマップすることができます。」

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


1
基本クラスで動作を実装することもあるので、非常に明確な回答と両方の状況を提供できること
VinKel

ここで発生する質問の1つは、なぜこれらのC#ボイラープレート宣言(明らかにそうです)が抽象クラスに存在する必要があるのか​​、そうでなければ簡潔で短い(したがってクラスを混乱させる)可能性があることです。私のC#プロジェクトには、多くの抽象クラスとインターフェイスがあります。そして、ほとんどの場合、Visual Studioでメソッド宣言をコピーして貼り付けます。
フォースバーグ2017年

5

実際にインターフェースを実装する必要はありません
インターフェースのメソッド/プロパティは、抽象的または仮想的にすることもできます。したがって、実際にそれらを実装するのはサブクラス次第です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.