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()”。为什么编译器不强迫我在“MyClass”中实现“func()”方法(它是从“IWork”接口派生的?它是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{
...
}

基本规则:您需要始终在实现所在的位置包含接口。因此,如果您在抽象类中创建一个方法并定义该方法的接口,则需要将该接口实现到您的抽象类中,然后所有子类将自动实现该接口。

事实上,接口有两种你可以使用它们的功能:

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 回答
1

我在我的解决方案中尝试了上面的类。它继承了抽象类,因此派生类具有 func() 方法定义。这就是它无法显示编译错误的原因。

于 2016-04-21T12:29:18.300 回答
0

func()未标记为abstractWorkClass因此您无需在派生自 的任何类中实现它WorkClass

WorkClass实现了IWork接口,所以你不需要实现它,MyClass因为它继承func()WorkClass.

于 2012-07-06T08:56:11.203 回答
0

由于抽象类中的func方法是非虚方法,所以编译器认为这个方法是接口的实现。

于 2012-07-06T08:56:47.873 回答
0

当您扩展MyClassWorkClass时,将继承该方法func()(已定义)。

因此,当实现接口时IWork,已经定义了方法“func()”。因此,在MyClass.

因此,该类MyClass是一个具体的类,因此您可以创建一个MyClass对象而不会出现任何编译错误。

于 2012-07-06T09:02:20.810 回答