使用Abstract类和接口进行多重继承

时间:2012-07-06 08:53:38

标签: c#

我在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();”在“MyClass”中,它来自接口“IWork”.Latter,我可以优雅地创建类“MyClass”的实例并调用函数“func()”。为什么编译器不强迫我在“MyClass”中实现“func()”方法(它来自“IWork”接口?这是C#中的一个缺陷吗?

7 个答案:

答案 0 :(得分:9)

在阅读这个主题时,我发现我不能轻易地将它全部放在我的脑海里,所以我写下了一段代码,它充当了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()必须在具体类中实现,因为抽象类不提供实现。

答案 1 :(得分: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

答案 2 :(得分:3)

因为abstract类实现了接口。

如果您的班级MyClass不会继承WorkClass,则会收到错误'MyClass' does not implement interface member 'IWork.func()'

但是你也从WorkClass继承,它实际上实现了接口所需的方法。

如果要强制从其继承的类实现它,可以将func()标记为抽象:

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

}

答案 3 :(得分:1)

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

答案 4 :(得分:0)

func()未在abstract中标记为WorkClass,因此您无需在任何源自WorkClass的类中实现它。

WorkClass实现IWork界面,因此您无需在MyClass中实施该界面,因为它会从func()继承WorkClass

答案 5 :(得分:0)

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

答案 6 :(得分:0)

当您将MyClass扩展为WorkClass时,方法func()(已定义)将被继承。

因此,当实现接口IWork时,已经定义了方法'func()'。因此,MyClass中没有更多未定义的方法。

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