11

私はC#.NETで次のコードを書いています

public interface IWork
{
    void func();

}
public abstract  class WorkClass
{
    public void func()
    {
        Console.WriteLine("Calling Abstract Class Function");
    }

}

public class MyClass:WorkClass,IWork
{

}

コンパイル時に、エラーは発生しませんでした。コンパイラは、メソッド「func();」の実装を強制していません。インターフェイス「IWork」から派生した「MyClass」では、クラス「MyClass」のインスタンスを適切に作成し、関数「func()」を呼び出すことができます。「IWork」インターフェイスから派生した「MyClass」に「func()」メソッドを実装するようにコンパイラが強制しないのはなぜですか?それは C# の欠陥ですか?

4

7 に答える 7

13

このテーマについて読んでいるうちに、頭の中ですべてを簡単にまとめることはできないことがわかったので、C# の仕組みのチートシートとして機能する次のコードを書きました。それが誰かを助けることを願っています。

public interface IMyInterface
{
    void FunctionA();
    void FunctionB();
    void FunctionC();
}

public abstract class MyAbstractClass : IMyInterface
{
    public void FunctionA()
    {
        Console.WriteLine( "FunctionA() implemented in abstract class. Cannot be overridden in concrete class." );
    }

    public virtual void FunctionB()
    {
        Console.WriteLine( "FunctionB() implemented in abstract class. Can be overridden in concrete class." );
    }

    public abstract void FunctionC();
}

public class MyConcreteClass : MyAbstractClass, IMyInterface
{
    public override void FunctionB()
    {
        base.FunctionB();
        Console.WriteLine( "FunctionB() implemented in abstract class but optionally overridden in concrete class." );
    }

    public override void FunctionC()
    {
        Console.WriteLine( "FunctionC() must be implemented in concrete class because abstract class provides no implementation." );
    }
}

class Program
{
    static void Main( string[] args )
    {
        IMyInterface foo = new MyConcreteClass();
        foo.FunctionA();
        foo.FunctionB();
        foo.FunctionC();
        Console.ReadKey();
    }
}

次の出力が得られます。

抽象クラスで実装された FunctionA() 。具体的なクラスではオーバーライドできません。

抽象クラスで実装された FunctionB() 。具体的なクラスでオーバーライドできます。

FunctionB() は抽象クラスに実装されていますが、必要に応じて具象クラスでオーバーライドされます。

抽象クラスは実装を提供しないため、FunctionC() は具象クラスで実装する必要があります。

于 2016-05-13T10:55:40.100 に答える
5

インターフェイスの背後にある概念をよりよく理解するために、実装の正しいコードを示します。

public interface IWork{
    void func();
}

public abstract class WorkClass,IWork{
    public void func(){
        Console.WriteLine("Calling Abstract Class Function");
    }
}

public class MyClass:WorkClass{
...
}

基本的なルール: 実装がある場所には常にインターフェイスを含める必要があります。したがって、抽象クラス内にメソッドを作成し、このメソッドのインターフェースを定義する場合、インターフェースを抽象クラスに実装する必要があります。そうすれば、すべてのサブクラスがこのインターフェースを自動的に実装します。

実際のところ、インターフェースには、それらを使用できる 2 種類の機能があります。

1) インターフェースを実装する任意のクラスの一般的な処理を提供する「実際の」インターフェースとして、(実際のクラス名を知らなくても) 1 つのインターフェースだけで数種類のクラスを処理できます。「処理」とは、メソッドの呼び出しを意味します。

2)他の(フレームワーク)プログラマーがあなたのコードを台無しにしないための助けとして。メソッドが別の名前に置き換えられないようにしたい場合は、すべての「必要な」メソッド名を含むクラスのインターフェイスを定義します。メソッドがどこにも呼び出されていない場合でも、プログラマはメソッド名を変更するとコンパイル エラー メッセージを受け取ります。

Myclassインターフェイスだけで簡単に扱えるようになりましたIWork

于 2013-02-22T20:56:04.120 に答える
3

abstractクラスがインターフェースを実装するためです。

クラスMyClassが から継承しない場合、WorkClassというエラーが表示されます'MyClass' does not implement interface member 'IWork.func()'

WorkClassしかし、インターフェイスが必要とするメソッドを実際に実装する からも継承します。

func()継承するクラスに次のように強制的に実装させたい場合は、抽象としてマークできます。

public abstract class WorkClass
{
    public abstract void func();

}
于 2012-07-06T08:54:56.907 に答える
0

に拡張MyClassするWorkClassと、メソッドfunc()(定義済み) が継承されます。

したがって、インターフェースIWorkが実装された時点で、メソッド「func()」はすでに定義されています。したがって、 には未定義のメソッドはもうありませんMyClass

したがって、クラスは具体的なクラスであり、コンパイル エラーなしMyClassでオブジェクトを作成できます。MyClass

于 2012-07-06T09:02:20.810 に答える
0

func()は のようにマークさabstractれてWorkClassいないため、 から派生するクラスに実装する必要はありませんWorkClass

WorkClassはインターフェイスを実装しているため、 から継承しているため、にIWork実装する必要はありません。MyClassfunc()WorkClass

于 2012-07-06T08:56:11.203 に答える
0

抽象クラスの func メソッドは非仮想メソッドであるため、コンパイラはこのメソッドがインターフェイスの実装であると認識します。

于 2012-07-06T08:56:47.873 に答える